【问题标题】:Can I access the id of the parent object inside a named_scope when fetching associated objects with the 'others' method?使用“其他”方法获取关联对象时,我可以访问 named_scope 中父对象的 id 吗?
【发布时间】:2010-02-01 23:07:27
【问题描述】:

假设您有两个模型:articlescomments

class Article < ActiveRecord::Base
  has_many :comments
end

您知道您可以将相关的 cmets 提取到这样的文章中:

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

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

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

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

【问题讨论】:

    标签: ruby-on-rails associations named-scope


    【解决方案1】:

    听起来你实际上想要的是一个关联扩展: 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
    

    【讨论】:

    • 最初,我想访问父对象的 id,以便在我的 named_scope 的 JOIN 语句中使用。这似乎是不可能的。但是,当我使用关联扩展并使用 proxy_owner 变量时,它可能的。所以,这并不是我想要的工作方式,但仍然很好。谢谢你的回答,马克。
    • proxy_owner() 是来自 Rails 3.1.0 的 deprecated。在较新版本的 Rails 中,可以使用扩展内的 @association.owner 方法或使用其他替代方法简单地访问所有者对象。代码 sn-ps 在我的答案中。
    【解决方案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 的类方法中,您现在可以在任何需要父文章 ID 的地方使用 get_article_id。使用代理关联,我无法做到这一点。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        适用于 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 返回调用.commentsArticle 对象。因此上面代码返回的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
        

        【讨论】:

          猜你喜欢
          • 2020-12-03
          • 2020-11-20
          • 2017-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-02
          • 2019-09-14
          相关资源
          最近更新 更多