我有一个订单,在创建订单时,也会创建一个新客户。为此,我有以下模型:
class Customer < ActiveRecord::Base
has_many :orders
has_many :subscriptions, through: orders
end
class Order < ActiveRecord::Base
belongs_to :customer
has_many :subscriptions
accepts_nested_attributes_for :customer
accepts_nested_attributes_for :subscriptions
end
class Subscription< ActiveRecord::Base
belongs_to :order
belongs_to :customer
end
在我的订单页面上,我有这样的表格:
= simple_form_for(@order) do |f|
= render 'order_fields', f: f
= f.simple_fields_for :subscriptions do |subscription|
= render 'subscription_fields', subscription: subscription
= f.simple_fields_for :customer do |customer|
= render 'customer_fields', customer: customer
= f.button :submit
在我的OrderController中,我有:
def new
@order = Order.new
@order.build_customer
@order.subscriptions.build
end
def create
@order = Order.new(order_params)
if @order.save
(.... etc ...)
end
private
def order_params
params.require(:order).permit(
:amount,
customer_attributes: [ :id, :email, :password, :password_confirmation],
subscriptions_attributes: [ :id, :product_id, :customer_id])
end
几乎一切顺利:
- 创建用户
- 订单已创建且具有customer_id = User.id
- 已创建订阅并具有order_id = Order.id
但不知何故,它不会将订阅与客户联系起来:(
我一直在 Subscription.customer_id = nil
有人可以指出我正确的方向吗?模型中有什么问题吗?还是在控制器里?我不知道在哪里看。
答案 0 :(得分:1)
你们的关系设置有点不同。我没有在订阅上创建customer_id
字段,而是希望您只拥有has_one :customer, through: :order
。
如果您这样做,您将不再需要订阅模型上的customer_id
属性。如果您想从订阅的世界视图中获取客户的ID,请拨打subscription.customer.id
。
您可能还想在模型中为您的关系添加inverse_of
名称(这总是一种很好的做法,可以最大限度地减少从数据库重新加载模型)。
所以,总的来说,我建议:
class Customer < ActiveRecord::Base
has_many :orders, inverse_of: :customer
has_many :subscriptions, through: orders
end
class Order < ActiveRecord::Base
belongs_to :customer, inverse_of: :orders
has_many :subscriptions, inverse_of: :order
accepts_nested_attributes_for :customer
accepts_nested_attributes_for :subscriptions
end
class Subscription< ActiveRecord::Base
belongs_to :order, inverse_of: :subscriptions
has_one :customer, through: :order # THIS IS THE KEY CHANGE
end
哦,然后您可以从customer_id
的允许属性中删除subscriptions_attributes
。
<强>更新强>
鉴于Subscription#customer_id意图与客户脱节 - &gt;订单 - &gt;订阅关系...忽略上面的内容(可能是inverse_of
内容除外)和......你应该可以这样做:
class Customer < ActiveRecord::Base
has_many :subscriptions, through: :orders, after_add: :cache_customer_id
private
def cache_customer_id(subscription)
subscription.update_column(:customer_id, self.id)
end
end
答案 1 :(得分:0)
谢谢pdobb!我现在正在添加order.controller:
def create
@order = Order.new(order_params)
if @order.save
@order.subscriptions.each { subscription| subscription.update_column(:customer_id, @order.customer.id) }
end