2012-01-15 8 views
0

多者数マッピングで記事とその作成者の関係を示す3つのモデルArticle,Author、およびAuthorLineがあります。モデルを保存する前に追加のアソシエーション属性を更新する

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秒対応のposition属性を更新する見当がつかないです。 1行目を削除して2行目のコメントを外すと、self.idが指定されていない可能性があるため、作成されたAuthorLineにはが含まれている可能性があります。

答えて

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が作成されると思いますが、このようなコールバックでは非常に明示的なチェックが必要です。

関連する問題