2016-01-05 57 views
2

我有兩個類爲:調用類方法的ActiveRecord協會

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 

的問題是,是否有更好的方式來知道哪些類方法被稱爲關聯對象(崗位)的ID 。一種方式(上面使用)是:post_id = self.new.post_id。 我敢打賭,有一種更清潔的方式,我不必爲了獲得post_id而創建對象。

回答

2

直接回答你的問題,

Comment.scope_attributes 

將返回一個散列那些屬性當前範圍的COM會成立。你可以測試一個關聯在這個上的效果是這樣的

我不確定我會使用這個雖然 - 有一個類方法只能在特定窗體的範圍上調用似乎有點奇怪。

+0

這是我正在尋找的確切答案。替代'post_id = self.new.post_id'(如你所建議的):'post_id = Comment.scope_attributes [「post_id」]'。 至於爲什麼我這樣做,它可能會派上用場,如果您想對某個帖子的所有評論進行一些處理並想調用'post.find(1).comments.process_comments'。這個'process_comments'可以是'Comment'的一個類方法。雖然沒有必要,但可能我想知道哪個「所有者」稱爲這個協會 - 這就是問題出現的地方。 –

3

情緒分析是你的一個重要的商業邏輯,也許它會增長很多,所以我認爲最好把它放在它自己的課堂上。

如果你這樣做,你將能夠只通過一個崗位分析儀(例如):

# 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 
+0

對我來說,這是一個好方法,因爲它會向未來展示你(編寫代碼的人)和可能的代碼維護者,這些代碼維護者偶然發現代碼,這是一個「正確」的地方分析邏輯。我並不主張反對在你的Active Record模型中加入一些邏輯(在這種情況下評論),我只是建議這是一個特定的邏輯,可以從適當的地方發展中受益。 –

+0

有沒有辦法獲得除'post_id = self.new.post_id'以外的關聯對象的ID?這只是一個示例代碼。真實的代碼不做任何情感分析。對帖子的所有評論都進行了非常小的處理,因此不需要新的課程。我們甚至不需要帖子ID來遍歷評論。這個問題是爲了好奇,我們如何在以這種方式調用靜態方法時獲取關聯對象的ID –