Rails宝典の第十七式:多対多Checkbox編集


今回は多対多の場合の編集についてお話しします.Checkboxを使用してこの作業を完了します.

class Category < ActiveRecord::Base
  has_and_belongs_to_many :products
end

class Product < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

CategoryとProductは多対多の関係です.次はProduct編集ページを書きます.

<%= error_messages_for 'product' %>

<p>
  Name<br/>
  <%= text_field :product, :name %>
</p>

<p>
  Price<br/>
  <%= text_field :product, :price %>
</p>

<p>
  <% for category in Category.find(:all) %>
  <div>
    <%= check_box_tag "product[category_ids][]", category.id, @product.categories.include?(category) %>
    <%= category.name %>
  </div>
  <% end %>
</p>

checkを使ってbox_tagはProductのcategoriesを編集します
そしてcategory_ids属性はProductのhas_and_belongs_to_many自動生成
次に、ProductsControllerのupdateメソッドコードを見てみましょう.

def update
  params[:product][:category_ids] ||= []
  @product = Product.find(params[:id])
  if @product.update_attributes(params[:product])
    flash[:notice] = 'Product was successfully updated.'
    redirect_to :action => 'show', :id => @product
  else
    render :action => 'edit'
  end
end

updateメソッドではparams[:product][category_ids]|=[]を使用してcategory_idsクリア
そうでなければ、すべてのcategory Checkboxをキャンセルすると、バックグラウンドsqlは空のcategoryを転送しません.ids配列ではなくcategory_を渡さないidsパラメータ
これによりcategory Checkboxがキャンセルされなくなります.