0

有關於節能ActiveRecord關聯的問題,需要你的幫助:)Rails的:ActiveRecord關聯的節約問題

我需要添加文章合併功能遺留代碼。

它的預期的工作方式如下:

  1. 合併「源」文章的文本「目標」的文章。
  2. 檢查「源」的評論,如果有的話,將它們重新關聯到「目標」。
  3. 銷燬「來源」文章。評論應該保留並與「目標」相關聯。

這裏是我的文章模型代碼(降低可讀性)。

class Article < Content 

    before_destroy :reload_associated_comments 

    has_many :comments, :dependent => :destroy, :order => "created_at ASC" do 

    def reload_associated_comments 
    unless self.comments.empty? 
     article = Article.find(@merge_with) 
     self.comments.each do |comment| 
     comment.article = article 
     article.save! 
     end 
    end 
    end 

    def merge_with(id) 
    @merge_with = id 
    article = Article.find(@merge_with) 
    if !article.nil? 
     text = article.body + body 
     article.body = text 
     article.save! 
     self.destroy 
     return article 
    end 
    nil 
    end 
end 

下面的評論模型(也降低):

class Comment < Feedback 
    belongs_to :article 
end 

的問題是,當我從before_destroy掛鉤什麼也沒有保存到數據庫返回。我通過以下檢查:

eval Article.find(target_article_id).comments 

保存引發沒有例外。我在這裏錯過了什麼?

在此先感謝!

這爲我工作

def merge_with(id) 
    @merge_with = id 
    article = Article.find(@merge_with) 
    unless article.nil? 
     text = article.body + body 
     article.body = text 
     article.save! 
     reload_associated_comments 
     self.reload 
     self.destroy 
     return article 
    end 
    nil 
    end 
+0

在該方法reload_associated_comments,它應該是comment.save!而不是article.save!我認爲:) – Zippie 2013-03-13 22:50:13

+0

也我不知道,但我認爲你不能調用self.destroy裏面的自我調用的方法。返回文章,然後從外部銷燬它(您稱之爲'merge_with'方法) – Zippie 2013-03-13 22:51:50

+0

'reload_associated_comments'方法用作'before_destroy'回調。如果我打電話給article.save !,這是不是意味着自動保存了評論?如果沒有,保存的正確順序是什麼。評論和文章,反之亦然? – niebelung 2013-03-13 22:55:22

回答

1

其實Rails的調用before_destroy回調之前的文章摧毀一切評論。這是可悲的如何鐵路工作。改變這種行爲意味着打破傳統應用程序。你可以找到關於這個問題在這裏的更多信息:https://github.com/rails/rails/issues/670

在我看來,最好的解決辦法是重寫destroy方法,擺脫回調的:

class Article < Content 

    def destroy 
    reload_associated_comments 
    super 
    end 

    has_many :comments, :dependent => :destroy, :order => "created_at ASC" do 

    def reload_associated_comments 
    unless self.comments.empty? 
     article = Article.find(@merge_with) 
     self.comments.each do |comment| 
     comment.article = article 
     comment.save! 
     end 
    end 
    end 

    def merge_with(id) 
    @merge_with = id 
    article = Article.find(@merge_with) 
    if !article.nil? 
     text = article.body + body 
     article.body = text 
     article.save! 
     self.destroy 
     return article 
    end 
    nil 
    end 
end 

而且,@Zippie提到的,你應該撥打comment.save!而不是article.save!

希望它有幫助!

+1

哇,什麼答案! alfonso,你不會說'reload_associated_comments'方法中的'article.save !'不對嗎?不應該是'comment.save'!如果它是正確的,它是怎麼回事?當我們在對象上放置一個'.save!'時,它會影響它的所有孩子? – Zippie 2013-03-13 23:21:24

+0

@Zippie好抓!是的,你是對的。編輯我的答案... – alf 2013-03-13 23:23:09

+0

我真的很高興,如果我不是,ActiveRecord會嚇到我了! :) – Zippie 2013-03-13 23:25:20