Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

After upgrading to Rails 4.1, new polymorphic associations are invalid when saving them along with their parent

After upgrading from Rails 3.2 to 4.1, the following code which used to work is now failing:

in a controller/spec:

post = user.posts.build
post.contacts << contact # contact is a persisted record
post.save! # now fails

I'm basically trying to save the post along with its associated contact, which is supposed to create a contact_publishment record on-the-fly. The error is on the new contact_publishment record: "Publishable can't be blank"

the model:

class Contact
  ...
  has_many :contact_publishments
  ...
end

class ContactPublishment
  ...
  belongs_to :publishable, polymorphic: true
  belongs_to :contact
  validates_uniqueness_of :publishable_id, :scope => [:contact_id, :publishable_type]
  validates_presence_of :contact, :publishable
  ...
end

class Post
  ...
  has_many :contact_publishments, as: :publishable
  has_many :contacts, through: :contact_publishments
  ...
end
like image 204
Yossi Shasho Avatar asked May 25 '14 12:05

Yossi Shasho


2 Answers

In Rails 3.2 owner model has been saved before perform validation nested association, in 4.1 validation before model saved, and because post not saved, validation

class ContactPublishment
    validates_presence_of :publishable

does not allow to pass validation (post not saved in db)

For resolve this, you may disable validation in Post model, (validation on ContactPublishment has been called from Contact model)

class Post < ActiveRecord::Base
      has_many :contact_publishments, as: :publishable, validate: false

or replace presence validation like this:

class ContactPublishment < ActiveRecord::Base
  validates_associated :publishable

change_column :contact_publishments, :publishable_type, :string, null: false
change_column :contact_publishments, :publishable_id, :integer, null: false

or do it through proxy_association

like image 67
Vakiliy Avatar answered Nov 02 '22 04:11

Vakiliy


I think the association is not updating because you do not have inverse_of setup between contact and contact_publishment.

From the docs about setting up a :through

If you are going to modify the association (rather than just read from it), then it is a good idea to set the :inverse_of option on the source association on the join model. This allows associated records to be built which will automatically create the appropriate join model records when they are saved.

like image 29
Steven Ferguson Avatar answered Nov 02 '22 04:11

Steven Ferguson