Флажки Rails HABTM не сохраняются в базе данных - PullRequest
0 голосов
/ 19 сентября 2011

Я начинаю программировать на Rails, и все, чего я хочу достичь, - это иметь список флажков, из которых я могу выбрать соответствующие категории для продукта. Я следил за Railscast по этому вопросу, но, похоже, он не работает для меня.

Я работаю с Rails 3.0.9 и Ruby 1.8.7.

У меня есть правильно настроенные модели и миграция для таблицы соединений. Когда я пытаюсь редактировать продукт, category_ids получает POSTed, но они никогда не сохраняются в базе данных.

Журнал:

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)

Модели:

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

Миграция:

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

Контроллер (метод обновления в контроллере продукта)

  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

Мой _form.html.erb в представлениях / продуктах

<%= 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.id, @product.categories.include?(category) %>
                <%= category.name %>
        </div>
   <% end %>

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

Контроллеры и представления были сгенерированы, используя изящные леса. Все остальное работает нормально, но значения из флажков не сохраняются в базе данных. Добавление их вручную через консоль рельсов работает просто отлично. Есть идеи, что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 19 сентября 2011

Модель вашего продукта имеет attr_accessible :name, :price, и поэтому журнал показывает WARNING: Can't mass-assign protected attributes: category_ids, когда вы пытаетесь выполнить @product.update_attributes(params[:product]) в вашем контроллере.

Попробуйте добавить category_ids к attr_accessible.

0 голосов
/ 19 сентября 2011

Когда я делал более или менее то же самое, мой check_box_tag выглядел по-другому:

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

В итоге я не нуждался в attr_accessible, хотя, как я упоминал в мой пост в блоге, описывающий ту же самую вещь , я все еще не уверен, почему нет.Я также использовал has_many:through.

...