开发者

Rails HABTM checkboxes don't save to database

I am beginning Rails programming and all I want to accomplish is to have a list of check boxes from which I can choose the corresponding categories for a product. I have followed the railscast on this matter, but it doesn't seem to work for me.

I work with Rails 3.0.9 and Ruby 1.8.7.

I have the models properly set up and the migration for the join table as well. When I try to edit a product, the category_ids get POSTed, but they are never saved to the database.

Log :

Started POST "/products/1" for 127.0.0.1 at Mon Sep 19 01:39:33 +0300 2011
  Processing by ProductsController#update as HTML
  Parameters: {"commit"=>"Update Product",     "authenticity_token"=>"x2Z5GGiNh9yLz6xjuQaMqdGW3Gw7dYe8dSghyrFpiYk=", "utf8"=>"���", "id"=>"1", "product"=>{"name"=>"Magicianulx2", "price"=>"121", "category_ids"=>["1"]}}
  Product Load (0.1ms)  SELECT "products".* FROM "products" WHERE "products"."id" = 1 LIMIT 1
WARNING: Can't mass-assign protected attributes: category_ids
Redirected to http://localhost:3000/products/1
Completed 302 Found in 10ms


Started GET "/products/1" for 127.0.0.1 at Mon Sep 19 01:39:33 +0300 2011
  Processing by ProductsController#show as HTML
  Parameters: {"id"=>"1"}
  Product Load (0.1ms)  SELECT "products".* FROM "products" WHERE "products"."id" = 1 LIMIT 1
Rendered products/show.html.erb within layouts/application (4.2ms)
Completed 200 OK in 11ms (Views: 6.1ms | ActiveRecord: 0.2ms)

Models :

class Product < ActiveRecord::Base
  attr_accessible :name, :price
  has_and_belongs_to_many :categories
end

class Category < ActiveRecord::Base
  attr_accessible :name
  has_and_belongs_to_many :products
end

Migration :

class AddCategoriesProducts < ActiveRecord::Migration
  def self.up
    create_table :categories_products, :id => false do |t|
      t.integer :category_id
      t.integer :product_id
    end
  end

  def self.down
    drop_table :categories_products
  end
end

Controller (update method in product controller)

  def update
    @product = Product.find(params[:id])
    if @product.update_attributes(params[:product])
      redirect_to @product, :notice  => "Successfully updated product."
    else
      render :action => 'edit'
    end
  end

My _form.html.erb in views/products

<%= form_for @product do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :price %><br />
    <%= f.text_field :price %>
  </p>

<% for category in Category.find(:all) %>
        <div>
                <%= check_box_tag "product[category_ids][]", category.i开发者_运维技巧d, @product.categories.include?(category) %>
                <%= category.name %>
        </div>
   <% end %>

<p><%= f.submit %></p>
<% end %>

The controllers and the views were all generated using nifty scaffolding. Everything else seems to work just fine, but the values from the check boxes don't get saved to the database. Adding them by hand via the rails console works just fine. Any ideas on what I am doing wrong?


Your Product model has attr_accessible :name, :price and that's why the log shows WARNING: Can't mass-assign protected attributes: category_ids when you try to do @product.update_attributes(params[:product]) in your controller.

Try adding category_ids to attr_accessible.


When I did more or less the same thing, my check_box_tag looked different:

<%= check_box_tag :category_ids,  
                  cat.id,  
                  @product.categories.include?(cat),  
                  :name => 'product[category_ids][]' %>  

I ended up not needing the attr_accessible, although as I mention in my blog post describing the exact same thing, I'm still not sure why not. I also used has_many:through.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜