【问题标题】:Arity of scopes in Rails 4Rails 4中范围的Arity
【发布时间】:2016-03-21 18:13:03
【问题描述】:

我知道如何检查 lambda 的数量,但我不知道如何从范围中提取它。

这个问题是 4 年前提出的:

https://groups.google.com/forum/#!topic/rubyonrails-core/7Cs0T34mj8c

所有,在对元搜索 gem 进行更改的过程中 我遇到了范围实施方式的问题 活动记录。为了在搜索中包含范围,我们传递名称 搜索方法的范围,如下所示:{:name_of_my_scope => 1}。 元搜索自动将"1" 作为参数传递给范围。 这会导致 ArgumentError 带有不带 争论。

我的意图是在调用和 如果范围没有参数,则删除"1"。我的 问题是范围的实现将范围选项包装在一个 将 *args 传递给块的 lambda (active_record/named_scope.rb: 106)。这导致对 arity 的调用始终返回 -1 范围定义所需的实际参数数量。

是否有不同的方法来实现允许公开的范围 范围定义中的arity?

例如。

class Post < ActiveRecord::Base  
     scope :today, lambda {where(:created_at => (Time.new.beginning_of_day...(Time.new.end_of_day)) }  
  end 

irb> Post.today.arity # => -1

在调用它之前,它会在寻找作用域的数量方面寻求帮助。

找到解决办法了吗?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 rails-activerecord


    【解决方案1】:

    scope 方法没有显式参数,如下所示

    irb(main):070:0> User.method(:active_users).parameters
    => [[:rest, :args]]
    

    :rest 表示参数作为数组收集。这允许一个人对任意数量的参数都没有参数。

    对于接受参数的范围,如果您使用错误数量的参数调用,您将收到ArgumentError - 有点像下面:

    ArgumentError: wrong number of arguments (1 for 2)
    

    我们可以利用这个 ArgumentError 来确定 arity,因为错误消息中存在 arity。

    让我警告你,这是一种 hack,如果你迫切需要弄清楚它可能会很有用大量基于 lambda 的作用域。

    我们可以在Model 中定义一个方法,它会尝试使用非常多的参数(比如 100 个参数)调用scope - 从而强制使用ArgumentError - 然后我们可以捕获消息并提取从它的arity。

    这种方法的可能实现如下所示:

    def self.scope_arity scope_symbol
        begin
            send(scope_symbol, (1..100).to_a) 
        rescue ArgumentError => e
            f = e.message.scan(/for\s+(\d+)/).flatten.first
            f.to_i.nonzero? || 0
        end
    end
    

    可能的用法如下:

    irb(main):074:0> User.scope_arity(:active_users)
    => 2
    

    【讨论】:

      猜你喜欢
      • 2016-07-11
      • 2016-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      相关资源
      最近更新 更多