This returns the maxium value, not the complete record:
self.prices.maximum(:price_field)
And currently, I find the record like this:
def maximum_price
self.prices.find(:first, :conditions => "price = #{self.prices.maximum(:price_field)}" )
end
Is this the correct way ? Because the above needs two SQL statements to make it work, and it somehow does not feel right.
Ps. Additionally, I want that if more than one record has the same "maximum" value, then it should get the one with the latest updated_at value. So that would mean another SQL statement??
Pps. Does anyone know of a good or detailed reference for AREL and non-AREL things in Rails? The Rails Guide for ActiveRecord query is just not enough!
(I'm using Rails 3)
===UPDATE===
Using AREL I do the following:
self.prices.order("updated_at DESC").maximum(:price_field)
But this only gives the maximum value, not the complete record :(
Also, is the use of maximum() really AREL?
How about something like this?
self.prices.order("price DESC").first
Related
I ask because a thorough Google search returns no clue as to how to do this.
I am trying to pull an example of a column field which is rarely used and is unfortunately littered with newlines and dashes even in empty ones, so I can't just ask for ones that have data. I need to ask for a column that has at least 10-15 characters or something like this. I can also imagine this query being useful for validating pre-existing data. I know about the validator that does this, but I'm not trying to validate, I'm trying to search.
Thanks!
Seems ActiveRecord does not support this. But you can do it anyway like (Mysql example)
Model.where("CHAR_LENGTH(text_field) = ?", 10)
in Postgres the same should work but in documentation it says to use char_length()
Also what you could do is on saving the record store the size of the field with a callback
before_save {|r| r.text_field_size = r.text_field.size}
With this you can now query with that, wich will be DB agnostic.
Model.where(text_field_size: 10)
I think you'll have to write so part of the request in SQL.
For MySQL, use something like :
Model.where("CHAR_LENGTH(field_name) >= ?", min_length)
I got some problems here, I can't make my find_by_sql request to render an ActiveRecord relation. Indeed, I need an activerecord relation to make a new request:
#searches = #searches.find_by_sql('SELECT *, COUNT( follower_id ) FROM follows GROUP BY followable_id LIMIT 0 , 3') if params[:only_famous_projects]
#project_pages = #project_pages.where(:project_id => #searches.pluck(:'followable.id')) if params[:only_famous_projects]
I can't use "pluck" without an activerecord relation. Therefore, I think I have to convert my sql request to an Activerecord request. However, as soon as I use "count" on ActiveRecord, I have an huge problem: I don't have on the end an ActiveRecord relation, but a FixNum!
I don't know where to find the answer anymore, I would be really gratefull if you could help me.
Thanks
find_by_sql will return an ActiveRecord object only if you call it with YourModel.find_by_sql.
Why not use the ActiveRecord query interface. It does a good job with calculations.
UPDATED
#searches = #searches.group(:followable_id).limit(3).offset(0).count(:follower_id) if params[:only_famous_projects]
Notice that it will give you a Hash containing the count for each followable_id.
Isn't LIMIT 0, 3 equivalent to LIMIT 3 ?
COUNT will always return a FixNUM, because you asked the database to count the number of rows.
You should really try to use find_by_sql as a last resort as it is only meant to bypass ActiveRecord for things that it can not do. And even for things that ActiveRecord doesn't support, you can always see if you can use the Squeel or Valium gems to handle edge-cases.
Another reason not to use find_by_sql is that, for example, using MySQL specific terms will lock you out of using other databases in the future.
We have an SQL query in our Rails 3 app.
#followers returns an array of IDs of users following the current_user.
#followers = current_user.following
#feed_items = Micropost.where("belongs_to_id IN (?)", #followers)
Is there a more efficient way to do this query?
The query you have can't really be optimized anymore than it is. It could be made faster by adding an index to belongs_to_id (which you should almost always do for foreign keys anyway), but that doesn't change the actual query.
There is a cleaner way to write IN queries though:
Micropost.where(:belongs_to_id => #followers)
where #followers is an array of values for belongs_to_id.
It looks good to me.
However if you're looking for real minimum numer of characters in the code, you could change:
Micropost.where("belongs_to_id IN (?)", #followers)
to
Micropost.where("belongs_to_id = ?", #followers)
which reads a little easier.
Rails will see the array and do the IN.
As always the main goal of the ruby language is readability so little improvements help.
As for query being inefficent, you shuld check into indexs on that field.
They tend to be a little more specific for each db - you have only specified generic sql. in your question.
Currently I can make the straight-up SQL query on my DB:
SELECT MAX(bar) FROM table_name
And it returns with the max value in that table. When I make what I consider to be an equivalent call in Rails, however, it does not work. I am calling:
Bar.all(:select => "Max(bar)")
This simply returns with:
[#<Bar >]
In the column I'm calling on is a series of identifying numbers, I'm looking for the largest one. Is there some other way of accessing this in Rails?
Assuming your model name is Bar and it has a column named bar, this should work:
Bar.maximum(:bar)
See the excellent Rails Guides section on Calculations :: Maximum for more info.
one more way
Bar.select("Max(bar) as max_bar").first.max_bar
What's the rails way to subtract a query result from another? A database specific SQL example would be:
SELECT Date FROM Store_Information
MINUS
SELECT Date FROM Internet_Sales
I'll throw this into the mix - not a solution, but might help with the progress:
Best I can think of is to use NOT IN:
StoreInformation.where('date NOT IN (?)', InternetSale.all)
That's Rails 3 - Rails 2 would be:
StoreInformation.all(:conditions => ['date NOT IN(?)', InternetSale.all])
But both of these will first select everything from internet_sales; what you really want is a nested query to do the whole thing in the database engine. For this, I think you'll have to break into find_by_sql and just give a nested query.
Obviously this assumes you're using MySQL! HTH.
Late answer but I think you meant :
activities = Activity.all
searches = activites.where(key: 'search')
(activites - searches).each do |anything_but_search|
p anything_but_search
end
You can substract two ActiveRecordsRelation and get the MINUS result, just like SQL would.
I am using Rails 4.2 so anything beyond that version should do the trick.