2012-01-15 110 views
0

我有三個模型Article,AuthorAuthorLine以多對多映射表示文章及其作者之間的關係。在保存模型之前更新其他關聯屬性

class Article < ActiveRecord::Base                                         
    has_many :author_lines, :dependent => :destroy                                           
    has_many :authors, :through => :author_lines, :dependent => :destroy, :order => 'author_lines.position' 

    attr_accessor :author_list 
end 

class Author < ActiveRecord::Base                                         
    has_many :author_lines                                           
    has_many :articles, :through => :author_lines                                     
end 

class AuthorLine < ActiveRecord::Base                                        
    validates :author_id, :article_id, :position, :presence => true 

    belongs_to :author, :counter_cache => :articles_count                                   
    belongs_to :article                                            
end 

AuthorLine模型有一個附加屬性position,它告訴作者的順序的文章。

下面是我在做什麼,以創建具有給定的作者姓名的一篇文章,在article.rb:

def author_list=(raw)                                           
    self.authors.clear                                            
    raw.split(',').map(&:strip).each_with_index do |e, i|                                   
    next if e.blank? 
    author = Author.find_or_create_by_name(e)                                     

    #1                                          
    self.authors << author                            

    #2 
    # AuthorLine.create(:author_id => author.id, :article_id => self.id, :position => i)                           
    end                                               
end 

的問題是我不知道什麼時候更新對應AuthorLine S的position屬性。如果刪除線#1,並取消對線路#2中,創建AuthorLine可以具有零arctile_id因爲self.id可能不給出。

回答

1

我可能會移動代碼在你的文章模型創建AuthorLines到after_create鉤。如果我理解正確的問題,這樣的事情應該做的伎倆:

after_create :set_author_line_positions 

def set_author_line_positions 
    self.authors.each_with_index do |author, index| 
    existing_author_line = AuthorLine.where("author_id = ? and article_id = ?", author.id, article.id).first 
    if existing_author_line 
     existing_author_line.update_attributes(:position => index) 
    else 
     AuthorLine.create(:author_id => author.id, :article_id => self.id, :position => index) 
    end 
    end 
end 

這樣的話,你只能拉閘後已創建您的文章,並有一個ID設置AuthorLine位置。這也檢查以確保已經創建了AuthorLine;我相信,一個AuthorLine會得到創建的每個作者被添加到文章的時間,但我喜歡在這樣的回調很明確的檢查。

相關問題