petehamilton / citier

CITIER (Class Inheritance & Table Inheritance Embeddings for Rails) is a solution for simple Multiple Class Inheritance in Rails.
88 stars 24 forks source link

Child doesn't get id set properly on-create #29

Closed DouweM closed 13 years ago

DouweM commented 13 years ago

I am using MySQL2 and the CITIER gem as currently available through git. I have a Status root-class and a LinkStatus subclass.

When I try to save a LinkStatus, it already has its id set to 0, causing future database-actions to fail:

pry(main)> link_status = LinkStatus.new
=> #<LinkStatus id: 0, type: "LinkStatus", [...]>
[set link_status properties]
pry(main)> link_status.id
=> 0
pry(main)> link_status.save
citier -> SAVING LinkStatus
citier -> Attributes for LinkStatus: {"link_url"=>"http://www.google.com"}
WARNING: Can't mass-assign protected attributes: id, type
   (0.1ms)  BEGIN
  SQL (0.2ms)  INSERT INTO `statuses` (`id`, `type`, [...]) VALUES (0, 'LinkStatus', [...])
   (0.2ms)  UPDATE statuses SET type = 'LinkStatus' WHERE id = 0
citier -> UPDATE statuses SET type = 'LinkStatus' WHERE id = 0
   (0.4ms)  COMMIT
   (0.1ms)  BEGIN
  SQL (33.1ms)  INSERT INTO `link_statuses` (`id`, `link_url`) VALUES (0, 'http://www.google.com')
   (0.4ms)  COMMIT
citier -> SQL : UPDATE statuses SET type = 'LinkStatus' WHERE id = 0
   (0.2ms)  UPDATE statuses SET type = 'LinkStatus' WHERE id = 0
=> true
pry(main)> link_status.id
=> 0

As you can see, before saving id is equal to 0 instead of nil, causing it not be overwritten by the actual value after the root-object is INSERTed into the statuses table. Because of this, the next INSERT query into link_statuses won't have same id as it's parent, causing the link_statuses row not to be linked to the statuses row.

It also causes all future database-actions on link_status to fail, as it goes looking for a record with id = 0.

The cause of this issue seems to be that the view_link_statuses.id column has 0 as its default value.

(For anyone else having this problem, I have temporarily fixed it by adding before_save { self.id = nil unless self.persisted? } to my Status model.)

DouweM commented 13 years ago

Fixed in pull request #31.