Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 关系点击数组方法而不是我的类方法_Ruby On Rails_Scopes - Fatal编程技术网

Ruby on rails 关系点击数组方法而不是我的类方法

Ruby on rails 关系点击数组方法而不是我的类方法,ruby-on-rails,scopes,Ruby On Rails,Scopes,在Rails 3.2模型中,我们希望创建一个“to_csv”类方法,从ActiveRecord作用域生成csv输出,如下所示: class Post # ... def self.to_csv(options = {}) CSV.generate(options) do |csv| scoped.each {|post| csv << record.attributes.values_at('title', 'text')} end

在Rails 3.2模型中,我们希望创建一个“to_csv”类方法,从ActiveRecord作用域生成csv输出,如下所示:

class Post
   # ...
   def self.to_csv(options = {})
     CSV.generate(options) do |csv|
       scoped.each {|post| csv << record.attributes.values_at('title', 'text')}
     end
   end
end
User.first.posts.to_csv
但是,该方法似乎被数组#to_csv方法覆盖。即使我这样做:

User.first.posts.scoped.to_csv
…并且User.first.posts.scoped的结果显式是一个ActiveRecord::Relation,我仍然使用了数组方法。如果我将该方法重命名为类似“to_csvx”的名称,它将按预期工作


我希望有人能解释ActiveRecord::Relation对象如何/为什么优先命中数组#to_csv方法而不是to_csv类方法。虽然这(一个期望被AR作用域调用的类方法)似乎是合理的,但我想知道整个想法是否存在固有的问题?

好的,回答我自己的问题太蹩脚了,但是基于@m_x和Railscast 239的评论,我更深入地了解了Rails源代码。。。我可以看到Relation
response\u to
honors,而
method\u missing
更喜欢数组方法,而不是为Relation明确定义的任何其他方法

# from rails/active_record/relation/delegation.rb

def respond_to?(method, include_private = false)
  super || Array.method_defined?(method) ||
    @klass.respond_to?(method, include_private) ||
    arel.respond_to?(method, include_private)
end

protected

def method_missing(method, *args, &block)
  if Array.method_defined?(method)
    ::ActiveRecord::Delegation.delegate method, :to => :to_a
    to_a.send(method, *args, &block)
  elsif @klass.respond_to?(method)
    ::ActiveRecord::Delegation.delegate_to_scoped_klass(method)
    scoping { @klass.send(method, *args, &block) }
  elsif arel.respond_to?(method)
    ::ActiveRecord::Delegation.delegate method, :to => :arel
    arel.send(method, *args, &block)
  else
    super
  end
end
因此,如果将ActiveRecord“作用域”类方法命名为与数组实例方法相同的方法,则关系将转换为数组,并且将调用数组方法而不是类方法


简单的解决方案:只需选择另一个方法名称。好的,回答我自己的问题太蹩脚了,但基于@m_x和Railscast 239的评论,我对Rails源代码进行了更深入的研究。。。我可以看到Relation
response\u to
honors,而
method\u missing
更喜欢数组方法,而不是为Relation明确定义的任何其他方法

# from rails/active_record/relation/delegation.rb

def respond_to?(method, include_private = false)
  super || Array.method_defined?(method) ||
    @klass.respond_to?(method, include_private) ||
    arel.respond_to?(method, include_private)
end

protected

def method_missing(method, *args, &block)
  if Array.method_defined?(method)
    ::ActiveRecord::Delegation.delegate method, :to => :to_a
    to_a.send(method, *args, &block)
  elsif @klass.respond_to?(method)
    ::ActiveRecord::Delegation.delegate_to_scoped_klass(method)
    scoping { @klass.send(method, *args, &block) }
  elsif arel.respond_to?(method)
    ::ActiveRecord::Delegation.delegate method, :to => :arel
    arel.send(method, *args, &block)
  else
    super
  end
end
因此,如果将ActiveRecord“作用域”类方法命名为与数组实例方法相同的方法,则关系将转换为数组,并且将调用数组方法而不是类方法


简单的解决方案:只需选择另一个方法名称。

表面上看,这似乎类似于,但问题的实际点是,如何通过将其链接到关系链的末端,而不是将其作为参数传递,来获取需要转换的记录。我只是在这里猜测:您的
数组#to_csv
方法似乎来自gem/monkey补丁(AFAIK,它不是来自rails本身)。也许这个gem也会修改
关系
,以便将
委托给_csv
委托给_a(请参阅)。这将解释您的问题,以及为什么使用另一个方法名有效。我应该注意到Ruby版本(1.9.3)这里显示了Array to_csv方法:我的错,我在Ruby 1.8中的一个旧框中尝试了这个方法。我不明白为什么ruby core中会有这样的方法?表面上看,这似乎很相似,但问题的实质是,我如何通过将这些记录链接到关系链的末端,而不是将它们作为参数传入,来获取需要转换的记录。我只是在这里猜测:您的
数组#to_csv
方法似乎来自gem/monkey补丁(AFAIK它不是rails本身的)。也许这个gem也会修改
关系
,以便将
委托给_csv
委托给_a(请参阅)。这将解释您的问题,以及为什么使用另一个方法名有效。我应该注意到Ruby版本(1.9.3)这里显示了Array to_csv方法:我的错,我在Ruby 1.8中的一个旧框中尝试了这个方法。我不明白为什么在ruby内核中会有这样的方法?回答你自己的问题并不是站不住脚的,事实上你甚至应该接受它。为社会做出贡献并帮助人们。。。很好地挖掘了源头。我觉得奇怪的是数组方法比关系方法更受欢迎,也许你应该建议在Github上安装rails补丁。回答你自己的问题并不难,事实上你甚至应该接受它。为社会做出贡献并帮助人们。。。很好地挖掘了源头。我觉得奇怪的是,数组方法比关系方法更受欢迎,也许你应该建议在github上安装rails补丁