Обновите дополнительный атрибут ассоциации перед сохранением модели - PullRequest
0 голосов
/ 15 января 2012

У меня есть три модели 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

Проблема в том, что я понятия не имею, когда обновлять атрибуты position соответствующих AuthorLine s.если я удалю строку # 1 и раскомментирую строку # 2, созданная AuthorLine может иметь ноль arctile_id, поскольку self.id может не быть задано.

1 Ответ

1 голос
/ 15 января 2012

Я бы, вероятно, переместил код для создания AuthorLines в after_create хук в вашей модели Article.Если я правильно понимаю проблему, что-то вроде этого должно сработать:

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

Таким образом, вы устанавливаете позиции AuthorLine только после того, как ваша статья уже создана и имеет идентификатор.Это также проверяет, чтобы убедиться, что AuthorLine уже был создан;Я считаю, что AuthorLine будет создаваться каждый раз, когда автор добавляется в статью, но мне нравится иметь очень явные проверки в обратных вызовах, подобных этому.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...