This project is archived and is in readonly mode.

#4001 ✓stale

nestedattributes for has_one and has_many association has different saving sequence

Reported by szetobo | February 19th, 2010 @ 11:14 AM

The models schema and its association is like this :-

ActiveRecord::Schema.define(:version => 20100219043257) do
  create_table "policies", :force => true do |t|
    t.string   "policy_no"
    t.datetime "created_at"
    t.datetime "updated_at"

  create_table "policy_items", :force => true do |t|
    t.integer  "policy_id"
    t.string   "item_type"
    t.decimal  "premium"
    t.datetime "created_at"
    t.datetime "updated_at"

class Policy < ActiveRecord::Base
  has_one :basic_plan, :class_name => "PolicyItem"
  has_many :topups, :class_name => "PolicyItem"

  accepts_nested_attributes_for :basic_plan, :allow_destroy => true
  accepts_nested_attributes_for :topups, :allow_destroy => true

class PolicyItem < ActiveRecord::Base
  belongs_to :policy, :foreign_key => "policy_id"

Then i add debug statement on every callback to verify the sequence between the parent and nested object and the result is :-

  • Policy before_validation callback
  • Policy validate callback
  • PolicyItem Topup before_validation callback
  • PolicyItem Topup validate callback
  • PolicyItem Topup after_validation callback
  • PolicyItem BasicPlan before_validation callback
  • PolicyItem BasicPlan validate callback
  • PolicyItem BasicPlan after_validation callback
  • Policy after_validation callback
  • Policy before_save callback
  • PolicyItem Topup before_save callback
  • PolicyItem Topup after_save callback
  • Policy after_save callback
  • PolicyItem BasicPlan before_save callback
  • PolicyItem BasicPlan after_save callback

As the result shown, the validation callback sequence is fine but the save callback sequence is a bit strange. The parent object's after_save callback has been invoked before the child's callback with has_one association. Child with has_many association seems behave normally as expected. Not sure it is by design or just a bug.

Comments and changes to this ticket

  • José Valim

    José Valim February 23rd, 2010 @ 09:35 PM

    • Assigned user set to “Eloy Duran”

    Eloy, could you please tell us if this is per design or not? Thanks mate!

  • José Valim

    José Valim February 24th, 2010 @ 10:56 AM

    • Assigned user changed from “Eloy Duran” to “José Valim”

    I talked with Eloy. The current behavior is inherited from previous Rails versions and we could change it. However, we need a valid reason to do that, so what is your use case? And feel free to try out a patch.

  • szetobo

    szetobo February 25th, 2010 @ 02:19 AM

    I use Policy as a centralize model to preform all the validation and saving logic to ensure the integrity of the whole policy. Initially I put all related models creation logic under the after_save callback of Policy and trigger it depends on certain event, like status change to certain stage etc. But then I discover that BasicPlan not yet save during after_save invocation of Policy.

    Now I have to move some of the logic into PolicyItem and build the association inside Policy's after_save callback. The reason I didn't want to put the logic under PolicyItem is because the related model creation logic is trigger by status change of Policy.

    Anyway, I agree that it can be solve without any changes in the Rails framework, although it is not that consistent and doesn't follow principle of least surprise.

    I'd very much like to contribute back but due to my experience on ruby and rails, I'm a bit loss after browsing through the source code. I will keep on trying that. Any good hacking guide or reference on rails framework would be helpful for newbie as me. Thanks anyway for the prompt response.

  • José Valim

    José Valim March 12th, 2010 @ 08:36 PM

    Hey mate. Any news? Can I help somehow?

  • Santiago Pastorino

    Santiago Pastorino February 2nd, 2011 @ 04:54 PM

    • State changed from “new” to “open”
    • Importance changed from “” to “Low”

    This issue has been automatically marked as stale because it has not been commented on for at least three months.

    The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.

    Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.

  • Santiago Pastorino

    Santiago Pastorino February 2nd, 2011 @ 04:54 PM

    • State changed from “open” to “stale”

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href=""></a>