Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

[PATCH] add :update_only option to accepts_nested_attributes_for

#2563

This option adds the ability for one-to-one associations to say "no i dont want the user to be able to create a new record just by leaving out the :id attribute", because at least in one of our applications, this would screw things up.


class Car < ActiveRecord::Base
  has_one :engine
  accepts_nested_attributes_for :engine, :update_only => true
end

class Engine < ActiveRecord::Base
  belongs_to :car
end

car = Car.create(:name => "Slow Car")

# this creates a new engine, since no engine exists
car.engine_attributes = {:ps => 40}
car.save!

# tunes the existing engine, doesn't create a new engine
car.engine_attributes = {:ps => 200}
car.save!

# does the same thing as above, :id is in fact ignored
car.engine_attributes = {:ps => 210, :id => car.engine.id}
car.save!

Reported by Michael Siebert · April 25th, 2009 @ 10:54 AM

State: resolved
Milestone: 2.x
Assigned to: Eloy Duran Eloy Duran
Importance: none

Activity

  1. Michael Siebert
    Michael Siebert

    now this is the patch with working tests (i forgot to rename the option in the tests, shame on me)

    May 14th, 2009 @ 04:41 PM

  2. José Valim
    José Valim

    The patch looks good, one suggestion though, those lines are duplicated:

        unless reject_new_record?(association_name, attributes)
          send("build_#{association_name}", attributes.except(*UNASSIGNABLE_KEYS))
        end
    

    You might get around it just changing the first conditional to:

      if update_only && existing_record = send(association_name)
    

    July 19th, 2009 @ 01:27 PM

  3. Joshua White
    Joshua White
    • Assigned user set to Eloy Duran

    I wrote the exact same sort of thing a few months back. There was a bit of discussion and I talked with Eloy a bit as well.

    My patch added two options, each applying to one sort of association. For one_to_ones I created blank_id_updates_existing_one_to_one (same as your update_only just requires there to be a blank, or the same id. Different ids wouldn't make sense anyways so its just semantics on that point.

    The important point for me was for collections I created :destroy_missing.

    I use a lot of 2-3 level nested forms and what destroy_missing does is it will actually delete nested attributes that aren't returned. Its dangerous, but in my case entirely safe, the nested objects I use this on are has_many and belongs_to, so if they aren't returned, it means they are no longer needed. ~six lines reduced my flex and html frontend logic and my controller logic, as well as transmission size.

    I've been using this module as a replacement for nested_attributes all over my application since then, and both options have worked perfectly thus far, and I'd really like to see both your update_only options and my destroy_missing options included in the next build.

    Is it reasonable to submit my destroy_missing features as a patch as well? I think it scares some people, but its just a few lines, doesn't even begin to effect the default behavior, saves the developer a LOT of hassle and repeated code, and is easier on the database then other methods. Any suggestions?

    Thanks
    -Josh

    July 22nd, 2009 @ 10:45 AM

  4. Repository
    Repository
    • State changed from new to resolved

    (from [7074c5a6294a0f53839accd53a4314af37d19248]) Add an :update_only option to accepts_nested_attributes_for for to-one associations. [#2563 state:resolved]

    Signed-off-by: Eloy Duran eloy.de.enige@gmail.com
    http://github.com/rails/rails/commit/7074c5a6294a0f53839accd53a4314...

    December 28th, 2009 @ 08:29 PM

  5. Eloy Duran
    Eloy Duran

    @Joshua Yes, please create a patch. Since I know you've been using it for a while, it seems to me it's time to go in Rails. Thanks

    December 28th, 2009 @ 08:43 PM

  6. Repository
    Repository

    (from [07b615fb897017d7acfaafa88606bc88be30f6e4]) Add an :update_only option to accepts_nested_attributes_for for to-one associations. [#2563 state:resolved]

    Signed-off-by: Eloy Duran eloy.de.enige@gmail.com
    http://github.com/rails/rails/commit/07b615fb897017d7acfaafa88606bc...

    December 28th, 2009 @ 08:52 PM

  7. bingbing