I am trying to make a named scope called :current_season where the it will correctly identify the records associated with the year we are in. Mostly easy enough except I want everything June and later to use the current year and everything prior to June to use the previous year.
in rails 3.1 I can easily use:
scope :current_season, lambda { where('season = ?',Time.now.year) } if Time.now.month >= 6
to get the scope to only work if we are at the end of the year and :
scope :current_season, lambda { where('season = ?',Time.now.year - 1) } if Time.now.month < 6
But it seems to wasteful to have to name it all twice and not use an if/else type of thing or be able to call in something I define below to show the exact year such as:
scope :current_season, lambda { where('season = ?',:current_season_year) }
def current_season_year
if Time.now.month >= 6
Time.now.year
else
Time.now.year - 1
end
end
But that just laughs at me when I try it. Is there a cleaner way? I will also have a scope :last_season and scope :previous_season most likely and they will follow similar logic.
thanks in advance for any advice!
Named scopes are just a DSL for writing a class methods that all have a similar functionality. Whenever you find them to be limiting you, just switch to a class method instead:
Of course, you could also include that in a scope like this:
It’s just going to define it as a class method on the model though. The tradeoff is clarity in the intention of a scope (it’s expected to return a chainable
ActiveRecord::Relation) versus clarity in documentation (if you run something like RDoc it isn’t going to notice a method available atModel.current_seasonbecause it hasn’t been defined in the code yet).Update:
There is one additional benefit from using a scope instead of a class method:
You can use a scope to create an object with certain parameters, as well. In this case, this isn’t very useful, but it’s worth considering when deciding which to use.