Rails - Create parent and child at the same time i

2019-08-31 07:47发布

问题:

I'm sur I do it wrong, but I can't see where. I've got this two models :

Subscription.rb (child)

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 (Parent)

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

When I want two create a new restorer, and a new subscription (at the same time) It doesn't work :

  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

回答1:

Looking at the comments and your code, it looks like the reason it isn't working is because of the validations on Subscriber. Restorer has one Subscription and Subscription belongs to a Subscriber. Nowhere are you creating the subscriber, hence why the subscription is failing it's validation. You need to either remove the validations, or set those validated properties (subscriber_id and subscriber_type) on Subscriber.

It's kinda a bit gross what you are trying to do in your create, but it should look something like this if you are going to do it that way:

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

Btw, its better to validate the relationship subscriber rather than the id subscriber_id:

validates :subscriber, presence: true