Search code examples
ruby-on-railsruby-on-rails-5ruby-on-rails-2

Rails 5: How to convert this named_scope to a scope


Simple question I hope.

How do I convert this named_scope line from a rails 2 app into a scope line for rails 5

original...

  named_scope :effective_on, lambda { |date|
    { :conditions => ['(effective_on IS NULL OR effective_on <= ?) AND (ineffective_on IS NULL OR ineffective_on > ?)', date, date] }
  }

I've tried this but it is just printing out the conditions line as a string...

  scope :effective_on, lambda { |date|
    { :conditions => ['(effective_on IS NULL OR effective_on <= ?) AND (ineffective_on IS NULL OR ineffective_on > ?)', date, date] }
  }

I suspect that is because "conditions" is deprecated for Rails 5.0 but when I try to replace it with "where" in this version it explodes in my face...

  scope :effective_on, lambda { |date|
    { where('(effective_on IS NULL OR effective_on <= ?) AND (ineffective_on IS NULL OR ineffective_on > ?)', date, date) }
  }

... Explodes in my face: the entire "where" line lights up red in my IDE and it tells me "Expected: =>"

And this is where I am stumped.


Solution

  • The issue is that the scope in the old Rails version returned a hash like { :conditions => 'some conditions } but in newer version it returns an active record relation (like the return value of the where method)

    So you have to change:

    scope :effective_on, lambda { |date|
      { :conditions => ['(effective_on IS NULL OR effective_on <= ?) AND (ineffective_on IS NULL OR ineffective_on > ?)', date, date] }
    }
    

    to

    scope :effective_on, lambda { |date|
      where('(effective_on IS NULL OR effective_on <= ?) AND (ineffective_on IS NULL OR ineffective_on > ?)', date, date)
    }
    

    without that { } around the where call