I have a Camping which has one Author. An Author has many Campings.
Getting the “top 5”, defined as “5 last campings” is done with:
@author.campings.order(:created_at).limit(5)
But I’d like this concept if “top 5” to be moved into the Camping model, this seems cleaner to me; after all, the Camping is the only one who knows what top is.
Something like
@author.campings.top
But how to define this on Camping? @author.campings is not a Camping, but an ActiveRecord::Relation. So something like following in models/camping.rb does not work:
# Scope for "top" campings
def top(amount)
self.order("created_at").limit(amount)
end
Used as
@author.top(5)
For now, I only need this “top” thing through the relation, @author in above-mentioned examples. For now, the definition of “top” is simply “last 5 campings”, but in a next iteration this will be more complex based on amount of views, ratings or other parameters and fields on Camping. Which leads me to believe that Camping is the correct place to define “top”, not Author.
I could add this to Author, but with my limited knowlegde that feels like a violation of the isolation pattern; Author suddenly needs to know about fields on Camping:
# Last 5 campings for this author
def top_campings(amount)
campings.order("created_at").limit(amount)
end
Used as
@author.top_campings(5)
How are such relations normally solved?
You would want to define
topin your Camping class this way:When you define it as a class method, it is available through the
ActiveRecord::Relation, so you can call@author.campings.top(5)