sphinx search with specific ordre - ruby

I have list of company (what sphinx return), I want to sort them to (company with store first) without overriding the weight of fields.
I tried :
:order => 'store DESC'
it's ok but the weight order has broken

If you want both the weight and the store to impact the ordering, you'll need to specify both - :order doesn't build upon existing values, it replaces them.
:order => 'weight() DESC, store DESC'

Related

Stripe Subscription Plans of Varying Amounts

I am working on a donation form for a charity and they have requested a monthly donation plan where the user can choose whatever amount they would like to give.
I know I can make individual plans (i.e. if they said monthly donations of $5, $10, or $20 dollars) I could make three different plans and subscribe users to them. Is there a way to avoid making new plans for every varying subscription amount?
The Stripe documentation recommends using the quantity parameter on the subscription.
https://stripe.com/docs/guides/subscriptions
Varying billing amounts
Some users need full flexibility in computing billing amounts. For
example, you might have a conceptual subscription that has a base cost
of $10 per month, and a $5 per-seat cost each month. We recommend
representing these billing relationships by creating a base plan that
is only $1 per month, or even $0.01 per month. This lets you use
quantity parameter to bill each user very flexibly. In an example
with a $10 base cost and three $5 seats, you could use a $1 per month
base plan, and set quantity=25 to achieve the desired total cost of
$25 for the month.
I don't think you can do it with Stripe.
What you can do is keep using Stripe and dynamically build the subscription plans using Stripe API or move to PayPal and use their Preapproval operation.
https://developer.paypal.com/docs/classic/api/adaptive-payments/Preapproval_API_Operation/
Your question seems self-defeating -- you can't have subscriptions of varying amounts without creating the corresponding plans!
The simplest way to handle recurring donations of varying amounts would be to create one plan per donator. For instance, you could do something like this:
# Create the plan for this donator
plan = Stripe::Plan.create(
:amount => params[:amount],
:currency => 'usd',
:interval => 'month',
:name => 'Donation plan for #{params[:stripeEmail]}',
:id => 'plan_#{params[:stripeEmail]}'
)
# Create the customer object and immediately subscribe them to the plan
customer = Stripe::Customer.create(
:source => params[:stripeToken],
:email => params[:stripeEmail],
:plan => plan.id
)
If you wish to avoid creating unnecessary plans, you could simply check if an appropriate plan already exists. The simplest way to do so would be to use a naming convention that includes the amount. For instance:
plan_id = '#{params[:amount]}_monthly'
begin
# Try to retrieve the plan for this amount, if one already exists
plan = Stripe::Plan.retrieve(plan_id)
rescue Stripe:: InvalidRequestError => e
# No plan found for this amount: create the plan
plan = Stripe::Plan.create(
:amount => params[:amount],
:currency => 'usd',
:interval => 'month',
:name => "$#{'%.02f' % (params[:amount] / 100.0)} / month donation plan",
:id => plan_id
)
# Create the customer object as in the previous example
(Note that in both these examples, I assumed that params[:amount] would be the donation's amount, as an integer in cents.)

Which is the most used name?

I am working on a ruby on rails site and I want to check its database for which is the most frequent name among the registered users.
There is a row called "First Name" for which I will go through. I don't mind about case sensitive right now.
Any convenient way to for example check what is the most popular name and then the second most popular, the third most popular and so on?
What I thought of is to get all users in an array and then do #users.each do |user|, then record the names in an array and after that to count the duplicates of each record that has more than one element recorded. I am not sure if its the proper way though.
Here is how you can do it using ActiveRecord:
User.group(:first_name).order('popularity desc').pluck(:first_name, 'count(*) as popularity')
This code translates to the SQL:
SELECT "users.first_name", count(*) as popularity FROM "users"
GROUP BY first_name
ORDER BY popularity
and you get something like:
[["John", 2345], ["James", 1986], ["Sam", 1835], ...]
If you want only the top ten names, you can limit the number of results simply by adding limit:
User.group(:first_name).order('popularity desc').limit(10).pluck(:first_name, 'count(*) as popularity')
Another option is to use the count API:
User.group(:first_name).count
=> {"Sam" => 1835, "Stefanos" => 2, ...}
# ordered
User.group(:first_name).order('count_all desc').count
=> {"John" => 2345, "James" => 1986, "Sam" => 1835, ...}
# top 3
User.group(:first_name).order('count_all desc').limit(3).count
=> {"John" => 2345, "James" => 1986, "Sam" => 1835 }
You could do the following SQL statement
select count(*) as count from users group by users.first_name order by count desc
Will return you the top most results. As Boris said, using just sql is the right way to go here.
Otherwise if you want to load all the users, you could do so by map-reduce.
#users.group_by(&:first_name).sort(&:count).reverse
Will give you an array of users sorted descending by their names.
Another way using ActiveRecord:
User.group(:first_name).count
Generated SQL is:
SELECT COUNT(*) AS count_all, name AS name FROM `users` GROUP BY name
Will output a hash of { name => number_of_occurances } e.g
{"John" => 29, "Peter" => 87, "Sarah" => 2}

ActiveRecord count of distinct days from created_at?

Is it possible to retrieve a count of distinct records based on a field value if the field needs to be interrogated (ideally, using ActiveRecord alone)?
For example, the following returns a count of unique records based on the 'created_at' field:
Record.count('created_at', :distinct => true)
However, is it possible to get a count of, say, unique days based on the 'created_at' field in a similar way?
A naive ActiveRecord example to explain my intent being:
Record.count('created_at'.day, :distinct => true)
(I know the string 'created_at' isn't a 'Time', but that's the sort of query I'd like to ask ActiveRecord.)
You need to group the records. For example
Record.group('DATE(created_at)').count('created_at')
tells you the number of rows created on each particular date, or
Record.group('DAYOFWEEK(created_at)').count('created_at')
would tell you the number of rows created on individual days of the week.
Beware that this with the usual active record setup this will do date calculations in UTC, if you want to do your calculations in a specific timezone you'll have to add that conversion to the group statement.

Complex date find and inject

I am building a financial reporting app with Ruby on Rails. In the app I have monthly financial statement objects (with 'revenue' as an attribute). For any single financial statement, I want show (1) year-to-date revenue, and (2) last-year-to-date revenue (calendar years are fine). Each object also has a Date (not Datetime) attribute called 'month' (watch out for 'month' variable name vs. 'month' method name confusion...maybe I should change that variable name).
So...
I think I need to (1) 'find' the array of financial statements (i.e., objects) in the appropriate date range, then (2) sum the 'revenue' fields. My code so far is...
def ytd_revenue
# Get all financial_statements for year-to-date.
financial_statements_ytd = self.company.financial_statements.find(:all,
:conditions => ["month BETWEEN ? and ?", "self.month.year AND month.month = 1",
"self.month.year AND self.month.month" ])
# Sum the 'revenue' attribute
financial_statements_ytd.inject(0) {|sum, revenue| sum + revenue }
end
This does not break the app, but returns '0' which cannot be correct.
Any ideas or help would be appreciated!
This statement may do what you want:
financial_statements_ytd.inject(0) {|sum, statement| sum + statement.revenue }
You can also look into ActiveRecord's sum class method - you can pass in the field name and conditions to get the sum.
What is the name of the field in financial_statement object that holds the value you want?
Supposing that the field name is ammount then just modify the inject statement to be:
financial_statements_ytd.inject {|sum, revenue| sum + revenue.ammount }

ActiveRecord query

I have the following ActiveRecords
class Product < ActiveRecord::Base
has_many :reviews
end
class Review < ActiveRecord::Base
belongs_to :product
end
Each review object contains a field named 'rating'
I wish to get a list of all products whose average rating is larger than a specific bound.
I don't understand how to use the find command to do this.
Does find let us do things like that?
I'd use SQL when queries start asking for things like conditions on aggregated values as this one does. There are various ways of achieving the result you want - this feels most straightforward to me:
bound = 3
products = Product.where('id in
(
select product_id
from reviews
group by product_id
having avg(rating) > ?)', bound)
-Yes, it can do it. Somthing like this should do the trick ...
Product.find(:all, :include => 'reviews', :conditions => ['review.rating > ?', min_rating])
Edit - Just reread your question. You want to use the average rating. I'd resort to SQL to do this, or if it is a common operation, calculate the average rating and store it in the product every time a rating is saved.

Resources