【问题标题】:Rails - Create parent and child at the same time in has_one belongs_toRails - 在 has_one belongs_to 中同时创建父母和孩子
【发布时间】:2014-09-09 13:08:46
【问题描述】:

我知道我做错了,但我看不出在哪里。 我有这两个模型:

Subscription.rb(子)

class Subscription < ActiveRecord::Base
  attr_accessible :state, :subscriber_id, :subscriber_type, :last_payment

  belongs_to :subscriber, polymorphic: true

  validates :subscriber_id, presence: true
  validates :subscriber_type, presence: true
end

restorer.rb(父)

class Restorer < User
  attr_accessible :firstname, :lastname, :restaurant_attributes, :subscription_attributes

  has_one :restaurant, dependent: :destroy, :autosave => true
  has_one :subscription, as: :subscriber, :autosave => true

  accepts_nested_attributes_for :restaurant
  accepts_nested_attributes_for :subscription

end

当我想要两个创建一个新的恢复器和一个新的订阅时(同时) 它不起作用:

  def create
    @restorer = Restorer.create params[:restorer]
    @restaurant = @restorer.build_restaurant params[:restorer][:restaurant_attributes]
    @subscription = @restorer.build_subscription params[:restorer][:subscription_attributes]

    if @restorer.save
      ...
    else
      ...
    end
  end

【问题讨论】:

  • 如果你使用save你应该替换createnew,你也不需要手动使用build_..(它应该自动工作)并尝试save!这会引发消息如果有问题。
  • 它引发了一个record_invalid错误...似乎有这个错误'subscriber_id should not be blank'
  • 这是因为您无法验证 nested_attributes 是否存在 id,因为它们本质上几乎是在 asynchronously 创建的,没有 id 将在保存时出现,直到保存完成后。如果您真的必须验证这一点,而我认为您不需要使用嵌套属性,那么您将不得不在一个步骤中创建这些对象,例如创建订阅者然后创建关联。您也许可以在交易中处理此问题,但我对此没有什么经验。
  • 好的,如何验证孩子的存在?
  • 我可以解释这一点,但 This Blog Post 比我在 SO 上做的更简洁。

标签: ruby-on-rails ruby belongs-to has-one


【解决方案1】:

查看 cmets 和您的代码,看起来它不起作用的原因是因为 Subscriber 上的验证。 Restorer 有一个 SubscriptionSubscription 属于一个 Subscriber。您在任何地方都没有创建订阅者,因此订阅未通过验证。您需要删除验证,或在Subscriber 上设置那些经过验证的属性(subscriber_id 和subscriber_type)。

您在创建中尝试做的事情有点粗俗,但如果您打算这样做,它应该看起来像这样:

def create
  @restorer = Restorer.create params[:restorer]

  # These two lines aren't needed if you are accepting nested attributes
  @restaurant = @restorer.build_restaurant params[:restorer][:restaurant_attributes]
  @subscription = @restorer.build_subscription params[:restorer][:subscription_attributes]

  subscriber = Subscriber.new params[:subscriber]
  @subscription.subscriber = subscriber

  if @restorer.save
    ...
  else
    ...
  end
end

顺便说一句,最好验证subscriber 的关系而不是 id subscriber_id

validates :subscriber, presence: true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 2014-10-01
    相关资源
    最近更新 更多