Given I got User.attachments and Attachment.visits as an integer with the number count.
How can I easily count all the visits of all images of that user?
Use ActiveRecord::Base#sum:
user.attachments.sum(:visits)
This should generate an efficient SQL query like this:
SELECT SUM(attachments.visits) FROM attachments WHERE attachments.user_id = ID
user.attachments.map{|a| a.visits}.sum
There's also inject:
user.attachments.inject(0) { |sum, a| sum + a.visits }
People generally (and quite rightly) hate inject, but since the two other main ways of achieving this have been mentioned, I thought I may as well throw it out there. :)
The following works with Plain Old Ruby Objects, and I suspect the following is marginally faster than using count += a.visits, plus it has an emoticon in it:
user.attachments.map(&:visits).inject(:+)
Related
Hi I'm working on a project and I need to take result of two database queries and combine them into one ActiveRecord_AssociationRelation, at the moment I have:
results.where(pos_or_neg: "neg").order("value DESC") + (results.where(pos_or_neg: "pos").order("value ASC"))
However this returns an array which doesn't work as I need to do more processing afterwards. I've tried:
results.where(pos_or_neg: "neg").order("value DESC").merge(results.where(pos_or_neg: "pos").order("value ASC"))
but this only seems to return the half of the results.
Thanks
results.order("pos_or_neg ASC,case when pos_or_neg="neg" then value else -1*value end DESC")
I believe using merge is the equivalent of an AND query in SQL. What you are looking for is an OR query.
Since Rails 5 this is one of the Active Record query methods that you can use!
http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-or
Try to replace your .merge with .or and see if that works better
I'm having some problems with my Ruby on Rails website. Let me explain.
I have a user model, it has many credits
In order to count, the credits for a user I do:
#user.credits.sum(:score)
This works fine.
Now have a model team, that has many users, and I want to find out the total number of credits, I found on another StackOverflow post this:
array.inject{|sum,x| sum + x }
So I thought for me it should look like that:
#team.users.inject{|sum,x| sum + x.credits.sum(:score)}
But this returns
#<User:0x00000101a7c180>
instead of the sum. Guess I'm doing something wrong. Don't hesitate if you have an idea.
Thanks
You have to set the initial value:
#team.users.inject(0){ |sum,x| sum + x.credits.sum(:score) }
You could also do:
#team.users.sum{ |x| x.credits.sum(:score) }
I'd like to check the first two chars of a number straight in my model. First I define the number of the current logged in user (devise):
user_number = current_user.number.first(2)
then I want to take that value and check it within a where statement in a "number" mobel, so I tried this
#numbers = Number.where(:number_value.first(2) => user_number)
which is obviously the same as
#numbers = Number.where(:number_value.first(2) => current_user.number.first(2))
No, that does not work.
How can I check the first 2 chars of the :number_value column in my model?
Any help is appreciated.
Many thanks.
Solution (SQLite)
#numbers = Number.where("number_value like '" + current_user.number.first(2) + "%'")
since this is not lazy loading I'm not convinced yet that it is the smartest solution. if you know any better, would be cool if you can share
First, you should read the ActiveRecord query guide. I'd also imagine that there's a much more straight forward way for you to accomplish your goal.
But, to answer your specific question, here's an approach that'd work with Postgresql.
Number.where("number_value::text like ?", current_user.number.to_s[0,2] + "%")
Say I have a collection of users and want to implement autocomplete on the usernames of those users. I looked at the mongodb docs and $regex seems to be one way to do this. Is there a better way? By better I mean more performant/better practice.
As suggested by #Thilo, you can use several ideas including prefixing.
The most important thing is to have very quick request (because you want autocomplete to feel instaneous). So you have to use query which will use properly indexes.
With regexp : use /^prefix/ (the important thing is the ^ to specify the beginning of line which is mandatory to make the query use index).
The range query is good too : { $gt : 'jhc', $lt: 'jhd' } }
More complicated but faster : you can store prefix-trees in mongo (aka tries) with entries like :
{usrPrefix : "anna", compl : ["annaconda", "annabelle", "annather"]}
{usrPrefix : "ann", compl : ["anne", "annaconda", "annabelle", "annather"]}
This last solution is very fast (if indexes on compl of course) but not space efficient at all. You know the trade-off you have too choose.
We do it using regex and it's fast as long as you have an index and you use /^value/
Be aware you can't use the case insensitive option with an index, so you may want to store a lower case version of your string as another field in your document and use that for the autocomplete.
I've done tests with 3 million+ documents and it still appears instantaneous.
If you are looking for prefixes, you could use a range query (not sure about the exact syntax):
db.users.find({'username': { $gt : 'jhc', $lt: 'jhd' } } )
And you want an index on the username field.
Just found out that this comparison is actually case-sensitive..Anyone know a case-insensitive way of accomplishing the same comparison?
CardReferral.all.map(&:email) - CardSignup.all.map(&:email)
I don't think there is any "direct" way like the minus operator, but if you don't mind getting all your results in lowercase, you can do this:
CardReferral.all.map(&:email).map(&:downcase) - CardSignup.all.map(&:email).map(&:downcase)
Otherwise you'll have to manually do the comparison using find_all or reject:
signups = CardSignup.all.map(&:email).map(&:downcase)
referrals = CardReferral.all.map(&:email).reject { |e| signups.include?(e.downcase) }
I'd suggest that reading a reference of Ruby's standard types might help you come up with code like this. For example, "Programming Ruby 1.9" has all methods of the Enumerable object explained starting on page 487 (find_all is on page 489).