【问题标题】:Is it possible to have a scope with optional arguments?是否可以有一个带有可选参数的范围?
【发布时间】:2012-05-07 11:47:27
【问题描述】:

是否可以编写一个带有可选参数的作用域,以便我可以调用带参数和不带参数的作用域?

类似:

scope :with_optional_args,  lambda { |arg|
  where("table.name = ?", arg)
}

Model.with_optional_args('foo')
Model.with_optional_args

如果给定了 arg(如 Unixmonkey 所述),我可以检查 lambda 块,但是在没有参数的情况下调用范围时,我得到了 ArgumentError: wrong number of arguments (0 for 1)

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord scope


    【解决方案1】:

    几周前我使用了scope :name, ->(arg1, arg2 = value) { ... },如果我没记错的话,它运行良好。与 ruby​​ 1.9+ 一起使用

    【讨论】:

      【解决方案2】:

      使用 *

      scope :with_optional_args,  -> { |*arg| where("table.name = ?", arg) }
      

      【讨论】:

        【解决方案3】:

        您可以根据给定的参数有条件地修改您的范围。

        scope :random, ->(num = nil){ num ? order('RANDOM()').limit(num) : order('RANDOM()') }
        

        用法:

        Advertisement.random # => returns all records randomized
        Advertisement.random(1) # => returns 1 random record
        

        或者,您可以提供一个默认值。

        scope :random, ->(num = 1000){ order('RANDOM()').limit(num) }
        

        用法:

        Product.random # => returns 1,000 random products
        Product.random(5) # => returns 5 random products
        

        注意:RANDOM() 显示的语法特定于 Postgres。显示的语法是 Rails 4。

        【讨论】:

          【解决方案4】:

          当然。

          scope :with_optional_args,  Proc.new { |arg|
            if arg.present?
              where("table.name = ?", arg)
            end
          }
          

          【讨论】:

          • 你不想在没有参数传递时包含一个后备吗?
          • 如果我不传递参数,我得到一个错误:ArgumentError: wrong number of arguments (0 for 1)
          • 您可以使用 Proc.new 而不是 lambda 来避免参数错误。请参阅有关此 here 的旧讨论
          【解决方案5】:

          只是想让您知道,根据guide,将参数传递给作用域的推荐方法是使用类方法,如下所示:

          class Post < ActiveRecord::Base
            def self.1_week_before(time)
              where("created_at < ?", time)
            end
          end
          

          这可以提供更简洁的方法。

          【讨论】:

            【解决方案6】:

            Ruby 1.9 扩展块具有与方法相同的功能(其中包含默认值):

            scope :cheap, lambda{|max_price=20.0| where("price < ?", max_price)}
            

            呼叫:

            Model.cheap
            Model.cheap(15)
            

            【讨论】:

              【解决方案7】:

              是的。只需像在方法中一样使用*

              scope :print_args, lambda {|*args|
                  puts args
              }
              

              【讨论】:

                猜你喜欢
                • 2020-05-03
                • 1970-01-01
                • 2010-10-01
                • 1970-01-01
                • 2021-08-15
                • 2011-07-26
                • 2011-04-15
                • 2012-05-22
                • 1970-01-01
                相关资源
                最近更新 更多