Tutorial :Has_many/belongs_to association not saving due to polymorphic associations?



Question:

I'm trying to create a log of attributes that have changed within each update to a certain message. The attributes are IssueStatus and IssueType, and both have two polymorphic associations with UpdateAction, that saves the changed_from_id and changed_from_type as well as changed_to_id and changed_to_type perfectly.

class IssueStatus < ActiveRecord::Base    has_many :update_actions, :as => :changed_to    has_many :update_actions, :as => :changed_from  end    class IssueType < ActiveRecord::Base    has_many :update_actions, :as => :changed_to    has_many :update_actions, :as => :changed_from  end    class Update < ActiveRecord::Base    has_many :update_actions  end    class UpdateAction < ActiveRecord::Base    belongs_to :changed_to, :polymorphic => true    belongs_to :changed_from, :polymorphic => true      belongs_to :update  end  

The problem is that trying to save a UpdateAction to Update.update_actions doesn't work. Rails returns true for both save and save!, but my development.log shows no SQL queries being performed. I cannot find out what I'm doing wrong, as nothing is logged (or I don't know how to find it). Working from the console:

>> action = UpdateAction.new  => #<UpdateAction id: nil, changed_from_id: nil, changed_from_type: nil, changed_to_id: nil, changed_to_type: nil, update_id: nil, created_at: nil, updated_at: nil>  >> action.changed_from = from  => #<IssueStatus id: 2, name: "Open", created_at: "2009-12-02 05:34:41", updated_at: "2009-12-02 05:34:41">  >> action.changed_to = to  => #<IssueStatus id: 1, name: "Closed", created_at: "2009-12-02 05:34:30", updated_at: "2009-12-02 05:34:30">  >> action.save  => true  >> update = Update.last  => #<Update id: 1, description: "Yawn", created_at: "2009-12-02 05:19:25", updated_at: "2009-12-02 05:19:25">  >> u.update_actions << action  => [#<UpdateAction id: 2, changed_from_id: 2, changed_from_type: "IssueStatus", changed_to_id: 1, changed_to_type: "IssueStatus", update_id: 1, created_at: "2009-12-02 05:35:16", updated_at: "2009-12-02 05:35:16">]  >> u.save  => true  >> u.update_actions  => [#<UpdateAction id: 2, changed_from_id: 2, changed_from_type: "IssueStatus", changed_to_id: 1, changed_to_type: "IssueStatus", update_id: 1, created_at: "2009-12-02 05:35:16", updated_at: "2009-12-02 05:35:16">]  >> u.reload  => #<Update id: 1, description: "Yawn", created_at: "2009-12-02 05:19:25", updated_at: "2009-12-02 05:19:25">  >> u.update_actions  => []  

Any help will be greatly appreciated, I guess I'm doing something wrong but I've been looking at it too long to figure out what. Thanks in advance!


Solution:1

Change your first line from

action = UpdateAction.new  

to

action = Update.last.update_actions.build  

Here's what's happening in your example (assuming you are referencing a real u, not update as Swanand suggested) - the u.save line is doing nothing because it only saves unsaved associated objects. You already saved a degenerate action, so the associated object save on a has_many doesn't think there is any work to do, since the field that needs to change is in the associated object. So, no where is the update_id field of action being saved. You could also call action.save and fix it.

I would have validate_presence_of update_id to prevent save and add a FK constraint in the DB on update_actions for update_id.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »