has_many:通过不会保存到数据库

时间:2011-12-30 04:03:08

标签: ruby-on-rails has-many-through categorization

我有Item&的关联通过分类分类:

class Item < ActiveRecord::Base
  has_many :categorizations
  has_many :categories, :through => :categorizations, :source => :category
end


class Category < ActiveRecord::Base
  has_many :categorizations
  has_many :items, :through => :categorizations, :source => :item
  attr_accessible :name
end

class Categorization < ActiveRecord::Base
  belongs_to :item
  belongs_to :category
end

产品/新:

<div class="container">
<%= render 'shared/error_create_item_messages'%>
<br/>

<%= form_for(@item, :html => {:multipart => true} ) do |f| %>

    <div class="clearfix">      
       <label>
         <%= f.label :name %>
      </label>
      <div class="input">       
         <%= f.text_field :name %>
      </div>
    </div>


     <div class="clearfix">
        <label>
         <%= f.label :category %>
        </label>

        <%= hidden_field_tag "product[category_ids][ ]", nil %>     
        <% Category.all.each do |category| %>
          <div class="input">           
               <%= check_box_tag "item[category_ids][ ]", category.id, 
                                            @item.category_ids.include?(category.id) %>
              <%= category.name %>
          </div>    
         <% end %>
     </div>     

     <div class="action">
        <div class="btn_create_item_align">
        <%= f.submit "Create item", :class=>"btn primary" %>
        </div>
     </div>

<% end %>
</div>

Categorizations_controller

class CategorizationsController < ApplicationController
   def create
     @categories = Category.all
     Categorization.create(:item_id => item.id, :category_id => category.id)
     Categorization.save
   end

  def edit
  end

end

Items_controller

def create
    @item = @current_user.items.build(params[:item])
    @categories = Category.all
    if @item.save
      redirect_to @item
    else
      render 'new'
    end
 end

问题是当我点击保存(创建项目),我检查分类表并检查控制台上,保存的项目仍然没有category_id。 因此,新项目及其属性(名称,描述,价格)将正确保存到DB,但不是类别。它不会保存到db。

有什么想法吗? (Rails中的新手) 感谢

1 个答案:

答案 0 :(得分:1)

表单POST到ItemsController #create,而CategorizationsController #create未被调用(您可以使用某些puts debugging验证这一点。)

您可以使用accepts_nested_attributes_for让Item的创建操作完成所有工作。诀窍是只创建选中其框的类别关联,并且可以使用:reject_if选项(see Rails API doc for more info)执行此操作:

应用程序/模型/ item.rb的:

class Item < ActiveRecord::Base
  has_many :categorizations
  has_many :categories, :through => :categorizations, :source => :category
  accepts_nested_attributes_for :categories, 
                                :reject_if => proc{|c| c[:persist].blank?}
end

然后,您可以为嵌套对象创建表单字段,每个类别一个复选框。

应用程序/视图/项目/ new.html.erb:

<%= form_for @item do |f| %>
  <%# stuff to generate item fields... %>

  <%= f.fields_for :categories do |cat| %>
    <%= cat.check_box :persist %>
    <%= cat.label :name, cat.name %>
  <%- end %>

  <%# submit button, etc. %>
<%- end %>

通过构建(但不保存)与项目关联的类别来填充要在创建新项目时选择的类别集。这有效地将代码从您的视图移动到控制器:

应用程序/控制器/ items_controller.rb:

def new  
  @item = Item.new  
  Category.all.each {|cat| @item.categories.build(cat.attributes) }  
end

该控制器操作中的puts params具有教育意义,因此您可以看到从表单发送的哈希值是什么样的。