Create does not work on parent object attributes with validation
mavenastic opened this issue · 2 comments
Disclaimer: This issue might be related to #9, although I'm not sure it is.
Let's say I have a Project model that has many items, the Item model being polymorphic.
class Project < ActiveRecord::Base
# ...
has_many :items
has_many :bookmarks, :through => :items, :source => :postable, :source_type => "Bookmark"
has_many :notes, :through => :items, :source => :postable, :source_type => "Note"
has_many :tasks, :through => :items, :source => :postable, :source_type => "Task"
end
class Item < ActiveRecord::Base
acts_as_superclass
attr_accessible :title, :description, :project_id, :postable_type, :postable_id
belongs_to :postable, :polymorphic => true
validates :title, :presence => true
end
Now, when I define a Bookmark model like so:
class Bookmark < ActiveRecord::Base
acts_as :item, :as => :postable
attr_accessible :favicon, :url
validates :url, :presence => true
end
And try to create one for a specific project in the console, it fails with a validation error on the common attribute, which was provided in the create statement:
p.bookmarks.create!(:title => "Foo Bar", :url => "http://www.foobar.com")
(0.3ms) BEGIN
SQL (0.6ms) INSERT INTO "bookmarks" ("created_at", "favicon", "updated_at", "url") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Wed, 26 Sep 2012 13:28:49 UTC +00:00], ["favicon", nil], ["updated_at", Wed, 26 Sep 2012 13:28:49 UTC +00:00], ["url", "http://www.foobar.com"]]
SQL (0.5ms) INSERT INTO "items" ("created_at", "description", "postable_id", "postable_type", "project_id", "title", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["created_at", Wed, 26 Sep 2012 13:28:49 UTC +00:00], ["description", nil], ["postable_id", 5], ["postable_type", "Bookmark"], ["project_id", nil], ["title", "Foo Bar"], ["updated_at", Wed, 26 Sep 2012 13:28:49 UTC +00:00]]
(0.3ms) ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Title can't be blank
However, if I use new
then save
, it works flawlessly:
bookmark = p.bookmarks.new(:title => "Foo Bar", :url => "http://www.foobar.com")
(0.3ms) BEGIN
(0.2ms) COMMIT
=> #<Bookmark id: nil, url: "http://www.foobar.com", favicon: nil, created_at: nil, updated_at: nil>
bookmark.save!
(0.3ms) BEGIN
SQL (0.5ms) INSERT INTO "bookmarks" ("created_at", "favicon", "updated_at", "url") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Wed, 26 Sep 2012 13:32:44 UTC +00:00], ["favicon", nil], ["updated_at", Wed, 26 Sep 2012 13:32:44 UTC +00:00], ["url", "http://www.foobar.com"]]
SQL (0.5ms) INSERT INTO "items" ("created_at", "description", "postable_id", "postable_type", "project_id", "title", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["created_at", Wed, 26 Sep 2012 13:32:44 UTC +00:00], ["description", nil], ["postable_id", 6], ["postable_type", "Bookmark"], ["project_id", nil], ["title", "Foo Bar"], ["updated_at", Wed, 26 Sep 2012 13:32:44 UTC +00:00]]
(2.1ms) COMMIT
=> true
I take it that the parent class methods are made available to the child model object during its initialization. Is there a workaround to this issue? Could it be related to issue #9?
Thanks in advance.
It is a strange behaviour!
even the new, save
method is not working (you have ["project_id", nil]
)
we have to take a closer look at it, but for now, my preferred method to create a postable
in project
is this:
# p = some project
Bookmark.create project: p, title: 'foo', ...
Thank you for the workaround, this indeed works:
Bookmark.create(project_id: p.id, title: "El Diablo", url: "http://eldiablo.es")
I'll try to troubleshoot and will post if I find something interesting; will use the workaround in the mean time.
Thanks!