#1308 ✓not-applicable
Scott Lowe

Update() fails when supplied with nested attributes

Reported by Scott Lowe | June 7th, 2010 @ 12:49 PM | in 1.0.2

When nested attributes are supplied to a model with an associated model, calling
update() fails. The parent model will be updated, but the child will not.

@person.update({'firstname' => 'James', 'lastname' => 'Smith', 'car' => {'make' => 'Ford', 'model' => 'Fiesta'}})
 => false

@person.update({'firstname' => 'James', 'lastname' => 'Smith'})
 => true

Nested Attributes work fine when supplied to create() followed by save() e.g.

@person = Person.create({'firstname' => 'James', 'lastname' => 'Smith', 'car' => {'make' => 'Ford', 'model' => 'Fiesta'}})

@person.save()
 => true

Comments and changes to this ticket

  • Scott Lowe

    Scott Lowe June 7th, 2010 @ 12:51 PM

    I should have added that I've tried getting the latest from Github with no luck, so the issue seems to be "fresh".

    -- Scott

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) June 7th, 2010 @ 04:34 PM

    • State changed from “new” to “unconfirmed”

    @Scott: Would you mind supplying a stand-alone script that reproduces the problem?

    I'm pretty sure updating nested objects is fairly well specced, but I want to see if there's a specific usage you have that isn't covered, or even if there's possibly some usage error there.

    It's hard to tell without models, but in the first statement you have is the equivalent of doing:

    @person.firstname = 'James'
    @person.lastname  = 'Smith'
    @person.car       = Car.new(:make => 'Ford', :model => 'Fiesta')  # assuming the model is Car
    @person.save  # would save car before person if it's a belongs_to() or after if it's has(1)
    

    I'm not sure if that was your intention or not.

  • Scott Lowe

    Scott Lowe June 7th, 2010 @ 05:38 PM

    Sure, I'll get back to you with a script.

    I'm new to DataMapper, but yes, I understand what you are saying about your example being equivalent.

    The reason this is significant is for those rails users out there that are posting back from
    an HTML form; mainstream examples (Yehuda on Rails Dispatch) will typically include
    controller code like:

      def update
        @person = Person.get(params[:id])
        
        if @person.update(params[:person])
          redirect_to persons_path
        else
          render 'edit'
        end
      end
    

    In this case, the params are nested attributes supplied by a form with nested fields using the fields_for() helper. The hapless developer might not be aware that they are using nested attributes in the params, but their code will fail.

    At first I thought it might be the Rails 3.0 beta code, but it seems to be the same from the console, when I execute with those raw attribute strings, and the debugger spent most of it's time in dm-core, rather than dm-rails or elsewhere.

    Apologies if I've got the wrong end of the stick!

    -- Scott

  • Scott Lowe

    Scott Lowe June 7th, 2010 @ 08:05 PM

    Stand-alone script(s) as requested with Gemfile for bundler goodness.

    I've reproduced two similar scenarios for you, one where a singular nested attribute reflects
    a "has 1" relationship, and a second (test2.rb) that uses a car collection to reflect a
    "has n" association.

    -- Scott

  • Scott Lowe

    Scott Lowe June 12th, 2010 @ 10:53 AM

    Hi Dan,

    Some clarification: I've done a little more reading and in Yehuda's Rails Dispatch blog example with nested resources, he doesn't use nested form fields to get the job done, so my bad there.

    However, Ryan Bates does use the Rails 'fields_for' helper for posting back nested resources. I've now realised that the models in Ryans example rely upon the ActiveRecord accepts_nested_attributes_for method which clearly doesn't apply to DataMapper right now. I also looked at Snusnu's "dm-accepts_nested_attributes" plugin, but I can see that's not ready for use with the update() method yet because of a "dirty resource" error, so I'll put that on the back burner for now.

    So with these things considered, I'm now wondering if perhaps DataMapper (core) isn't intended to work in this way, and perhaps it's wrong of me to expect it to? Perhaps this 'bug' report isn't a bug? What do you think?

    -- Scott

  • Martin Gamsjaeger (snusnu)

    Martin Gamsjaeger (snusnu) June 12th, 2010 @ 05:37 PM

    Scott,

    What's the exact issue you have with dana? (dm-accepts_nested_attributes) Last time I checked, specs ran fine. In general, a "dirty resource" error means that you try to call update on a resource that is already dirty, and this is on purpose. So I tend to think that dana actually just works as it's expected, but maybe you change the resource before dana handles the update internally?

  • Scott Lowe

    Scott Lowe June 13th, 2010 @ 10:27 AM

    Martin - Woo! dm-accepts_nested_attributes worked!

    You were right - I'd accidentally placed the ID field of my Parent object into my HTML form which was posting it in the params, and of course DM thought that I'd messed with the object for this (now obvious) reason.

    Thanks to dm-accepts_nested_attributes everything is now working as I'd hoped :o)

    Apologies for my DataMapper noob-ness. I hope that my confusion will at least help others Googling for "nested attributes".

    -- Scott

  • Martin Gamsjaeger (snusnu)

    Martin Gamsjaeger (snusnu) June 13th, 2010 @ 04:53 PM

    • Assigned user set to “Martin Gamsjaeger (snusnu)”

    Cool, glad it solves the problem for you Scott! Dan, do you think we should mark this resolved, or do you want to investigate more?

  • Martin Gamsjaeger (snusnu)

    Martin Gamsjaeger (snusnu) June 24th, 2010 @ 06:46 PM

    • Milestone set to 1.0.2
    • State changed from “unconfirmed” to “not-applicable”

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

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

Attachments

Pages