Rails 4 scope with argument

后端 未结 2 1830
别跟我提以往
别跟我提以往 2021-01-01 14:34

Upgrading Rails 3.2. to Rails 4. I have the following scope:

# Rails 3.2
scope :by_post_status, lambda { |post_status| where(\"post_status = ?\", post_status         


        
相关标签:
2条回答
  • 2021-01-01 14:41

    From the Rails edge docs

    "Rails 4.0 requires that scopes use a callable object such as a Proc or lambda:"

    scope :active, where(active: true)
    
    # becomes 
    scope :active, -> { where active: true }
    


    With this in mind, you can easily rewrite you code as such:

    scope :by_post_status, lambda { |post_status| where('post_status = ?', post_status) }
    scope :published, lambda { by_post_status("public") }
    scope :draft, lambda { by_post_status("draft") }
    

    In the event that you have many different statuses that you wish to support and find this to be cumbersome, the following may suit you:

    post_statuses = %I[public draft private published ...]
    scope :by_post_status, -> (post_status) { where('post_status = ?', post_status) }
    
    post_statuses.each {|s| scope s, -> {by_post_status(s.to_s)} }
    
    0 讨论(0)
  • 2021-01-01 14:42

    Very simple, just same lambda without arguments:

    scope :by_post_status, -> (post_status) { where('post_status = ?', post_status) }
    scope :published, -> { by_post_status("public") }
    scope :draft, -> { by_post_status("draft") }
    

    or more shorted:

    %i[published draft].each do |type|
      scope type, -> { by_post_status(type.to_s) }
    end
    
    0 讨论(0)
提交回复
热议问题