我有点新的Rails,这是我的第一篇文章StackOverflow。Rails嵌套窗体与has_many:通过,不保存数据加入表
说我有3种型号:
class Product < ActiveRecord::Base
default_scope :order => :title
has_many :line_items
has_many :promo_products
has_many :promotions, :through => :promo_products, :foreign_key => :promotion_id
before_destroy :ensure_not_referenced_by_any_line_item
before_destroy :ensure_not_referenced_by_any_promo_product
validates :title, :presence => true, :uniqueness => true
validates :description, :presence => true
validates :price, :numericality => {:greater_than_or_equal_to => 0.01}
private
def ensure_not_referenced_by_any_line_item
if line_items.empty?
return true
else
errors.add(:base, 'Line Items present')
return false
end
end
def ensure_not_referenced_by_any_promo_product
if promo_products.empty?
return true
else
errors.add(:base, 'Some promotions are still in effect')
return false
end
end
end
class Promotion < ActiveRecord::Base
CART_OR_PRODUCT = ['Cart', 'Product']
PROMOTION_TYPE = ['Percentage based', 'Value based']
has_many :promo_products
accepts_nested_attributes_for :promo_products
has_many :products, :through => :promo_products, :foreign_key => :product_id
accepts_nested_attributes_for :products
#attr_accessible :promo_products_attributes, :title, :description, :cart_or_product, :promotion_type, :discount, :minimum_price, :minimum_quantity
validates :title, :description, :presence => true
validates :cart_or_product, :inclusion => {:in => CART_OR_PRODUCT, :message =>
"is invlaid. Please select a valid option"}
validates :promotion_type, :inclusion => {:in => PROMOTION_TYPE, :message =>
"is invalid. Please select a valid option"}
validates :discount, :minimum_price, :numericality => {:greater_than_or_equal_to => 0.00}
validates :minimum_quantity, :numericality => {:greater_than_or_equal_to => 0}
end
class PromoProduct < ActiveRecord::Base
belongs_to :promotion
belongs_to :product
accepts_nested_attributes_for :products
end
在促销新的一页,我想展现的产品,可能是一个促销活动的一部分名单。用户可以选择0个,1个或更多产品,具体取决于促销类型。
在promotions_controller的新动作,我建这样的:
@promotion.promo_products.build.build_product
在促销_form,我需要展示的产品,为用户选择列表。我做了一个嵌套表格,如:
<%= form_for(@promotion) do |f| %>
<!-- other promotion fields -->
<%= f.fields_for :promo_products do |pp| %>
<%= pp.fields_for :products do |p| %>
<div class="field">
<%= f.label "Products" %><br />
<%= collection_select :promo_product, :product_id, Product.all, :id, :title {:selected => @promotion.product_ids}, {:multiple => true} %>
</div>
<% end %>
<% end %>
<% end %>
我有2个问题。
- 首先我的代码抛出一个错误: 引发ArgumentError在PromotionsController#新 没有相关发现名称'产品。它已被定义? 如果我更改了PromoProduct模型行: accepts_nested_attributes_for:产品 到 accepts_nested_attributes_for:产品 然后有没有错误,一切工作正常。
数据未保存到promo_product表中。我在promo_product控制器中创建了以下动作:
def create @promotion = current_promotion products = Product.select(:id => params[:product_id]) products.each do |p| promo_product = @promotion.promo_products.build(p) promo_product.save end #@promo_product = PromoProduct.new(params[:promo_product]) redirect_to promotions_path end
我该如何解决这个问题?
谢谢。
我设法解决了这个问题。遵循这里给出的想法[链接](https://gist.github.com/2820294)。似乎工作正常。从promo_product创建操作中删除创建,并通过促销创建操作使其生效。 –