我正在尝试根据以下答案创建来自已知的父product_type的产品: How to create a nested child from parent object in ruby on rails 4
产品控制器:
...
def new
@product_type = ProductType.find params[:product_type_id]
@product = @product_type.products.new
end
def create
@product_type = ProductType.find params[:product_type_id]
@product = @product_type.products.build(product_params)
if @product.save
flash[:notice] = 'Product created.'
redirect_to(:action => 'index')
else
render("new")
end
end
新方法的行为符合预期。创建运行时,它会获取:product_type_id而不是整数的哈希值,如控制台中所示:
参数:{“utf8”=>“✓”,“authenticity_token”=>“dmGMF6uENfUtkwgwI6GrnvBawIFA6M6Z / ELikQn9gGs =”,“product”=> {“year”=>“2015”,“brand_id”= >“9”,“name”=>“a”,“description”=>“b”,“thumbnail_desc”=>“”,“category_ids”=> [“”,“29”], “product_class_ids”=> [“”],“image_base”=>“”,“media_embed”=>“”,“vendor_sku”=>“”,“msrp”=>“22”,“price_override “=>”“,”visible“=>”1“,”available“=>”1“},”product_type_id“=> {”39“=>”“},”commit“=> ; “保存”}
所以,发现失败了。因此,抛出的错误是未知密钥:39。
模型:ProductTypes有许多产品和产品属于ProductTypes。
这是Rails2的一个早该重写的重写。在那里,@ product_type实例变量从new保存到create。
感谢您的考虑和帮助。
以下是产品形式:
<%= form_for([:admin, @product]) do |form| %>
<% if @product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@product.errors.count, "error") %> prohibited this page from being saved:</h2>
<ul>
<% @product.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<table cellpadding="0" cellspacing="0" class="admintable">
<tr>
<th>Year</th>
<td><%= form.text_field :year, :size => 5 %></td>
</tr>
<tr>
<th>Brand</th>
<td><%= form.select(:brand_id, @brands.map {|b| [b.name, b.id]}) %></td>
</tr>
<tr>
<th>Product Name</th>
<td><%= form.text_field :name, :size => 30 %></td>
</tr>
<tr>
<th>Description</th>
<td><%= form.text_area :description, :cols => 60, :rows => 30 %></td>
</tr>
<tr>
<th>Thumbnail Description</th>
<td><%= form.text_area :thumbnail_desc, :cols => 60, :rows => 5 %></td>
</tr>
<tr>
<th>Categories</th>
<td>
<%= form.collection_select :category_ids, Category.sorted, :id, :name, {}, {:multiple => true, include_blank: true, :size => 20 } %>
</td>
</tr>
<tr>
<th>Product Class</th>
<td>
<%= form.collection_select :product_class_ids, ProductClass.options_for_select(@product.product_type_id), :id, :name, {}, {:multiple => true, include_blank: true, :size => 4 } %>
</td>
</tr>
<tr>
<th>Image Base</th>
<td><%= form.text_field :image_base, :size => 40 %></td>
</tr>
<tr>
<th>Media Embed Code</th>
<td><%= form.text_area :media_embed, :cols => 60, :rows => 5 %></td>
</tr>
<tr>
<th>Vendor SKU</th>
<td><%= form.text_field :vendor_sku, :size => 30 %></td>
</tr>
<% if @product_type.has_price? -%>
<tr>
<th>MSRP</th>
<td><%= form.text_field :msrp, :size => 5 %></td>
</tr>
<tr>
<th>BW Price</th>
<td><%= form.text_field :price_override, :size => 5 %></td>
</tr>
<% end -%>
<tr>
<th>Visible?</th>
<td><%= form.check_box :visible %></td>
</tr>
<tr>
<th>Available?</th>
<td><%= form.check_box :available %></td>
</tr>
<% unless @product.active -%>
<tr>
<th>Active</th>
<td><%= form.check_box :active %></td>
</tr>
<% end -%>
<%= hidden_field :product_type_id, "#{@product_type.id}" %>
<tr>
<th> </th>
<td><%= form.submit "Save" %></td>
</tr>
</table>
<% end %>
产品型号:
class Product < ActiveRecord::Base
belongs_to :brand
belongs_to :product_type
has_and_belongs_to_many :categories
has_and_belongs_to_many :colors
has_and_belongs_to_many :product_classes
validates_presence_of :name, :categories
validates_presence_of :msrp, :if => Proc.new { |p| p.price_override != nil }
validates_numericality_of :year, :greater_than => 2007, :allow_nil => true
validates_numericality_of :msrp, :price_override, :greater_than => 0, :allow_nil => true
scope :sorted, lambda { order("name ASC") }
scope :notdeleted, lambda { where(:deleted_at => nil) }
def display_name(model = nil)
str = model ? model.actual_name : name
str = "#{brand_year_prefix} #{str}" if product_type.name_has_prefix?
str
end
def brand_year_prefix
str = brand.display_name if product_type.name_includes_brand
str = "#{year} #{str}" if product_type.name_includes_year
str.strip
end
def model_name(model, include_brand = false)
str = model.actual_name
str = "#{brand.display_name} #{str}" if include_brand
str = "#{year} #{str}" if product_type.model_name_includes_year
str
end
def price
price_override ? price_override : msrp
end
def onsale
price_override ? '<span class="red">Sale: ': '<span class=""> '
end
def has_product_pricing?
price != nil
end
def has_one_price?
has_product_pricing? && models.all? { |m| !m.has_model_pricing? }
end
def can_be_purchased?
visible? && available? && deleted_at.nil? && (!product_type.has_models || models.any? { |m| m.can_be_purchased? })
end
def real_image_path
image_base.blank? ? AppConfig.default_product_image : image_base
end
def thumb_image_path
real_image_path + "-t.jpg"
end
def standard_image_path
real_image_path + "-s.jpg"
end
def large_image_path
real_image_path + "-l.jpg"
end
def active
deleted_at.nil?
end
def active=(val)
self.deleted_at = [nil, '', '0', false].member?(val) ? Time.now : nil
end
def self.compare_year(a, b)
a_has_year = !a.year.blank? && a.product_type.name_includes_year?
b_has_year = !b.year.blank? && b.product_type.name_includes_year?
return 0 if !a_has_year && !b_has_year
return -1 if a_has_year && !b_has_year
return 1 if b_has_year && !a_has_year
b.year <=> a.year
end
def self.compare_brand(a, b)
a_has_brand = !a.brand.nil? && a.product_type.name_includes_brand?
b_has_brand = !b.brand.nil? && b.product_type.name_includes_brand?
return 0 if !a_has_brand && !b_has_brand
return -1 if a_has_brand && !b_has_brand
return 1 if b_has_brand && !a_has_brand
a.brand.display_name <=> b.brand.display_name
end
end
product_type型号:
class ProductType < ActiveRecord::Base
has_many :product_classes
has_many :products
validates_presence_of :name
scope :sorted, lambda { order("name ASC") }
scope :notdeleted, lambda { where(:deleted_at => nil) }
def active
deleted_at.nil?
end
def active=(val)
self.deleted_at = [nil, '', '0', false].member?(val) ? Time.now : nil
end
end
答案 0 :(得分:0)
要解决这个问题,我必须重构代码。重构的新方法:
<%= form_for([:admin, @product], :url => {:action => 'create', :product_type_id => @product_type.id}) do |form| %>
<%= render :partial => 'form', :locals => {:form => form} %>
<div class="form-buttons">
<%= submit_tag("Create #{@product_type.name}") %>
</div>
<% end %>
然后_form.html.erb只有html表单元素。