我有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中的新手) 感谢
答案 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
具有教育意义,因此您可以看到从表单发送的哈希值是什么样的。