我对 Rails 有点陌生,这是我在 StackOverflow 上的第一篇文章。
假设我有 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个问题。
- 首先我的代码抛出一个错误:PromotionsController#new 中的 ArgumentError 没有为名称“产品”找到关联。已经定义了吗?如果我将 PromoProduct 模型中的行更改为:accepts_nested_attributes_for :products 为 accept_nested_attributes_for :product 那么没有错误,一切正常。
数据不会保存到 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
我该怎么办?
谢谢你。