2

我通过分类有一个项目和类别的关联:

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>

分类_控制器

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。因此,新项目及其属性(名称、描述、价格)被正确保存到数据库,但不是类别。它不会保存到数据库。

有任何想法吗?(Rails 新手)谢谢

4

1 回答 1

1

表单 POST 到 ItemsController#create,并且 CategorizationsController#create 没有被调用(您可以通过一些puts调试来验证这一点)。

您可以使用accepts_nested_attributes_for项目的创建操作来完成所有工作。诀窍是只创建选中框的类别关联,您可以使用:reject_if选项来执行此操作(有关更多信息,请参阅 Rails API 文档):

应用程序/模型/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意义,因此您可以看到从表单发送的哈希是什么样子的。

于 2011-12-30T08:06:23.977 回答