3

假设您有两个模型:articlescomments.

class Article < ActiveRecord::Base
  has_many :comments
end

您知道您可以获取相关文章的相关评论,如下所示:

article = Article.first
article.comments # => SELECT * FROM "comments" WHERE ("comments".article_id = 123)

有没有办法article_id在named_scope中显式访问(123)?

我需要这个用于连接另一个表的复杂 named_scope。基本上,named_scope 将取决于从关联的父对象调用是否有意义(article.comments.my_named_scope不是 Comments.my_named_scope)。

我不想将 id 作为named_scope 的参数传递。因此,我不想将 传递article_id给命名范围... lambda { |article| ...}并使用 访问 id "... #{article.id} ...",而是想以某种方式访问​​该article_id方法others使用的 this ,这是我从has_many关联中获得的。

4

4 回答 4

4

听起来你实际上想要的是一个关联扩展: http: //guides.rubyonrails.org/association_basics.html#association-extensions

特别是proxy_owner, 这将是有问题的@article

例如:

class Article < ActiveRecord::Base
  has_many :posts do
    def sample_extension
      puts "Proxy Owner #{proxy_owner}"
    end
  end
end

@article.posts.sample_extension
于 2010-02-02T15:01:32.133 回答
2

一直在努力解决同样的问题。你可以试试这个,比使用关联扩展更优雅:

class Article < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  def self.get_article_id
    self.new.article_id
  end
end

@article = Article.new
@article.posts.get_article_id

在 Post 的类方法中,您现在可以get_article_id在任何需要父文章 ID 的地方使用。使用代理协会,我无法做到这一点。

于 2011-05-10T01:17:03.210 回答
0

我喜欢@ajkochanowicz 的解决方案,但看起来那里涉及到数据库命中(Rails 3.2.x),所以只是提醒一下,考虑到您已经在某处拥有父对象这一事实,这并不是很理想。

于 2014-04-30T04:48:33.747 回答
0

对于 Rails 4 及更高版本

在 Rails4+ 中更新的方法是:

class Article < ActiveRecord::Base
  has_many :comments do
    def my_named_scope
      puts "Scope Owner = #{@association.owner}"
    end
  end
end

article = @article.comments.my_named_scope

在范围内my_named_scope@association.owner返回被调用的Article对象.comments。因此,article上面代码返回的结果与@article对象相同。

替代方法

如果您不想使用扩展并且宁愿避免“创建一个新对象并从那里获取 id”方法(如 Chanpory 的回答所述),这里是如何做到的:

class Article < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  def self.get_article_id
    Comment.scope_attributes["article_id"] # scope_attributes returns a hash of all the attributes inherited from the owner of this scope
  end
end

@article = Article.find(10)
@article.comments.get_article_id  # returns 10
于 2016-01-08T01:07:38.297 回答