Rails query through association limited to most recent record?
If you aren't going to go with @rubyprince's ruby solution, this is actually a more complex DB query than ActiveRecord can handle in it's simplest form because it requires a sub-query. Here's how I would do this entirely with a query:
SELECT users.*
FROM users
INNER JOIN books on books.user_id = users.id
WHERE books.created_on = ( SELECT MAX(books.created_on)
FROM books
WHERE books.user_id = users.id)
AND books.complete = true
GROUP BY users.id
To convert this into ActiveRecord I would do the following:
class User
scope :last_book_completed, joins(:books)
.where('books.created_on = (SELECT MAX(books.created_on) FROM books WHERE books.user_id = users.id)')
.where('books.complete = true')
.group('users.id')
end
You can then get a list of all users that have a last completed book by doing the following:
User.last_book_completed
Include only the latest/newest associated record with active record?
This is a working scope with lambda to pass parameters to the scope to select the genre id.
scope :latest_with_genre, lambda do |searched_genre_id|
joins(:books)
.where('books.date_of_publication = (SELECT MAX(books.date_of_publication) FROM books WHERE books.author_id = authors.id)')
.where("books.genre_id = #{searched_genre_id}").group('author.id')
end
This answer Rails query through association limited to most recent record? from
Pan Thomakos helped me for the scope.
This answer Pass arguments in scope from keymone helped me for passing argument
How to fix this n+1 query: Limiting child association to most recent record in JSON api response
One solution is to define a has_one with an association scope:
has_one :most_recent_task, -> { order(created_at: :asc) }, class_name: "Task"
You can then use includes
to eagerly load the data:
>> Project.includes(:most_recent_task).all
Project Load (0.3ms) SELECT "projects".* FROM "projects" LIMIT $1 [["LIMIT", 11]]
Task Load (0.5ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."project_id" IN (1, 2) ORDER BY "tasks"."created_at" ASC
Note that it's querying all tasks for each project, not just the most recent one. But there's no N+1, and Project#most_recent_task
is nicely expressive.
Rails fetch all including last row from association
How about creating an another association like this:
class Scheme < ActiveRecord::Base
has_one :current_nav, -> { order('id DESC').limit(1) }, class_name: 'Nav'
end
Now you can:
Schema.includes(:current_nav).all
or:
Schema.includes(:current_nav).last(10)
will eager load only last nav of the queried schemes.
Explanation: includes
is one of the methods for retrieving objects from database in ActiveRecord
. From the doc itself:
Active Record lets you specify in advance all the associations that
are going to be loaded. This is possible by specifying the includes
method of the Model.find call. With includes, Active Record ensures
that all of the specified associations are loaded using the minimum
possible number of queries.
And, since we have the association setup with current_nav
, all we had to do is to use it with includes
to eager load the data. Please read ActiveRecord querying doc for more information.
How to get last N records with activerecord?
Updated Answer (2020)
You can get last N records simply by using last method:
Record.last(N)
Example:
User.last(5)
Returns 5 users in descending order by their id.
Deprecated (Old Answer)
An active record query like this I think would get you what you want ('Something' is the model name):
Something.find(:all, :order => "id desc", :limit => 5).reverse
edit: As noted in the comments, another way:
result = Something.find(:all, :order => "id desc", :limit => 5)
while !result.empty?
puts result.pop
end
Related Topics
Create a Pivot Table With Postgresql
What Are Best Practices For Multi-Language Database Design
Optimise Postgresql For Fast Testing
Is There a Max Function in SQL Server That Takes Two Values Like Math.Max in .Net
How to Do a Case Sensitive Search in Where Clause (I'M Using SQL Server)
MySQL Delete from With Subquery as Condition
Group by to Combine/Concat a Column
Strings as Primary Keys in SQL Database
Unknown Column in 'Field List' Error on MySQL Update Query
MySQL Unknown Column in on Clause
Is There a Lastindexof in SQL Server
Multiple Inner Join SQL Access
Why Is There No Product Aggregate Function in SQL