【问题标题】:Calling Class method via Rails ActiveRecord Association通过 Rails ActiveRecord 关联调用 Class 方法
【发布时间】:2016-04-09 22:55:44
【问题描述】:

我有两个类:

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post

  # Class method
  # does some analysis on all the comments of a given post  
  def self.do_sentiment_analysis
     post_id = self.new.post_id  # Is there a better way to get post_id?

     # real code that does something follows

  end

end


# Class method is called on a post object like this:
Post.find(1).comments.do_sentiment_analysis

问题是是否有更好的方法来知道调用类方法的关联对象(post)的id。一种方法(上面使用的)是:post_id = self.new.post_id。 我敢打赌,有一种更简洁的方法,我不必为了获取 post_id 而创建对象。

【问题讨论】:

    标签: ruby-on-rails ruby activerecord associations


    【解决方案1】:

    直接回答您的问题,

    Comment.scope_attributes
    

    将返回 Comment 上当前范围将设置的那些属性的哈希值。您可以像这样测试关联对此的影响

    我不确定我是否会使用它 - 拥有一个只能在特定表单的范围内调用的类方法似乎有点奇怪。

    【讨论】:

    • 这是我正在寻找的确切答案。 post_id = self.new.post_id 的替代品(如您所建议的):post_id=Comment.scope_attributes["post_id"]。至于我为什么要这样做,它可能会在您想对帖子的所有 cmets 进行一些处理并想致电 post.find(1).comments.process_comments 的情况下派上用场。这个process_comments 可以是Comment 的类方法。虽然没有必要,但可能我想知道哪个“所有者”调用了这个关联 - 这就是问题所在。
    【解决方案2】:

    情感分析是你的一个重要的业务逻辑,说不定还会增长很多,所以我觉得还是放在自己的类里比较好。

    如果您这样做,您将能够将帖子传递给分析器(例如):

    # app/models/analyzer.rb
    class Analyzer
      def initialize(post)
        @post = post
      end
    
      def sentiment
        @post.comments.each do |comment|
          do_something_with comment
          # ... more real stuff here
        end
      end
    
      def some_other_analysis
      end
    
      private
      def do_something_with(comment)
        # ...
      end
    end
    

    现在你可以重写你的例子了:

    Analyzer.new(Post.find(1)).sentiment
    

    【讨论】:

    • 在我看来这是一个好方法,因为它将向未来的您(编写代码的人)和可能偶然发现代码的代码维护者展示“正确”放置分析逻辑的地方。我不主张在你的 Active Record 模型上添加一些逻辑(在这种情况下是评论),我只是建议这是一个特定的逻辑,可以从适当的地方成长。
    • 除了post_id = self.new.post_id之外,有没有其他方法可以获取关联对象的ID?这只是一个示例代码。真实代码不做任何情绪分析。对帖子的所有 cmets 进行了非常小的处理,因此不需要新的类。同样,我们甚至不需要 post ID 来遍历 cmets。这个问题是为了好奇以这种方式调用静态方法时我们如何获取关联对象的id
    猜你喜欢
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 1970-01-01
    相关资源
    最近更新 更多