Using if with scope on the model

I am trying to create a named area with the name: current_season, where it will correctly identify the records associated with the year we are in. It’s basically easy enough, except that I want to use the current year only in June and later, and all until June for use in 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 opportunity to work only 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 wasteful to call it all twice and not use the if if else type, or be able to call what I define below to show the exact year, for example:

 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 it just laughs at me when I try. Is there a cleaner way? I will also have a scope: last_season and scope: previous_season, most likely, and they will follow the same logic.

Thanks in advance for any advice!

+4
source share
1 answer

Named scopes are just DSLs for writing class methods that have similar functionality. Whenever you find that they limit you, just switch to the class method:

 def self.current_season year = Time.now.month >= 6 ? Time.now.year : Time.now.year - 1 where('season = ?', year) end 

Of course, you can also include this in an area like this:

 scope :current_season, do # same code as above... end 

He will simply define it as a class method on the model. The trade-off is clarity in the intent of the area (it should return the ActiveRecord::Relation chain) compared to clarity in the documentation (if you run something like RDoc, it will not see the method available in Model.current_season , because it hasn’t not yet defined in code).

Update:

There is another advantage to using scope instead of a class method:

 User.admin.create name: 'Corey' #=> <User: @name="Corey" @admin=true> 

You can use the scope to create an object with specific parameters. In this case, this is not very useful, but it is worth considering when deciding what to use.

+12
source

All Articles