レールに関連付けを設定する適切な方法にまだ苦労しています。最終的に、ほとんどの作業をモデルに任せたいという結論に達しました。私の基本モデルはかなり単純です。書籍のモデル、賞のモデル、および 2 つをリンクする book_awards のモデルがあります。book モデルから book_awards を作成したいと思います。
class Book < ActiveRecord::Base
has_many :book_awards, :inverse_of :book
has_many :awards, :through => :book_awards
end
私が新しい本を扱っているとき、可能な賞のリストを作成するのはとても簡単です。次のようになります: (いずれの場合award_list
も として渡されますAward.some_scope
)
def build_book_awards(award_list)
award_list.each do |award|
book_awards.build(:award => award)
end
end
ただし、既存の本を扱うときは、関連付けが既に存在するかどうかを確認する必要があります。かなり簡単なアプローチは次のとおりです。
def build_book_awards(award_list)
award_list.each do |award|
book_rewards.build(:award => award) if book_awards.find{|s| s.award == award}.nil?
end
end
問題は、これが賞を受賞順にリストしないことです。代わりに、既存の book_awards を最初にリストし、次にその本が受賞していない賞をリストします。純粋に審美的な理由から、これはぞっとするものだと思います。関連付けを毎回同じ順序でリストしたい。
次に、次のコードを思いつきました。これにより、項目が整然とリストされ、編集ページが美しく見えますが、ユーザーが更新を続行しない場合、既存の関連付けが削除されるという容認できない副作用があります。
def build_book_awards(award_list)
current = book_awards.clone
book_awards.clear
award_list.each do |award|
book_award = current.find{|s| s.award == award}
if book_award
book_awards.push(book_award)
else
book_awards.build(:book => book)
end
end
end
私の頭の中の問題は、ビルドが関連付けを作成し、それを関連付けリストの最後に追加することです。それを構築して、好きな場所に挿入する方法が必要です。