hzamani / acts_as_relation

Multi table Inheritance for rails
http://hzamani.github.com/acts_as_relation/
MIT License
180 stars 58 forks source link

Create does not work on parent object attributes with validation #21

Closed mavenastic closed 12 years ago

mavenastic commented 12 years ago

Disclaimer: This issue might be related to https://github.com/hzamani/acts_as_relation/issues/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.

hzamani commented 12 years ago

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', ... 
mavenastic commented 12 years ago

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!