0

I'm trying to create a record and it's associated records from a nested form using strong parameters. My primary model is:

class MaterialDonationRequest < ActiveRecord::Base
  has_many :donation_items, dependent: :destroy
  accepts_nested_attributes_for :donation_items, allow_destroy: true
  validates :name, presence: true

  attr_accessor :due_on_event, :date, :donation_items_attributes, :event_id
end

My associated (nested) model is:

class DonationItem < ActiveRecord::Base
  validates :name, presence: true
  belongs_to :material_donation_request
  belongs_to :global_profile

  validates :name, presence: true
  attr_accessor :_destroy
end

In my material_donation_requests_controller.rb, I have the following for strong parameters:

    def material_donation_request_params
      params.require(:material_donation_request).permit(:name, :description, :event_flag, :due_on_event, :date, :event_id, donation_items_attributes: [:id, :name, :description, :amount, :_destroy])
    end

Here's the line in my create method where I create the object:

    @material_donation_request = MaterialDonationRequest.new(material_donation_request_params)

After doing this, @material_donation_request is created and populated correctly from the form. But the associated donation_items do not get created. For instance, in the debugger, when I enter @material_donation_request.donation_items.first, Rails returns nil.

For reference, here is what Rails returns for material_donation_request_params in the manual tests I'm running:

{"name"=>"Name", "description"=>"", "due_on_event"=>"true", "date"=>"", "donation_items_attributes"=>{"0"=>{"name"=>"", "amount"=>"1", "_destroy"=>""}, "1427122183210"=>{"name"=>"", "amount"=>"2", "_destroy"=>""}}}

Why isn't Rails creating the associated objects from the form as well? Everywhere I've looked, it seems like this structure should create everything, and a subsequent save should save everything (or at least throw validation errors as in this case-see update below). Is there something I'm missing?

Update

Since it was brought up in the answers, yes, the material_donation_params shown above would not pass validation. That's the scenario I've been manually testing. It should generate a validation error on save, but instead, simply saves the MaterialDonationRequest with no errors of any kind, and saves nothing to DonationItems.

To be clear, though, if I fill out the form completely and get the following material_donation_request_params:

{"name"=>"Name", "description"=>"", "due_on_event"=>"true", "date"=>"", "donation_items_attributes"=>{"0"=>{"name"=>"first", "amount"=>"1", "_destroy"=>""}, "1427122183210"=>{"name"=>"second", "amount"=>"2", "_destroy"=>""}}}

and then do @material_donation_request.save, it only saves the MaterialDonationRequest, and not any of the DonationItems.

Final Update

Okay. I've deleted my previous "final update" because what I wrote, and what I wrote in some of the comments was wrong. What ended up fixing this was not an update to Rails 4.1.8. I ran the bundle update command before actually saving the gem file with the new Rails version. So really, what ended up fixing this was simply updating all the gems that didn't have fixed version numbers. God only knows why things weren't working with the previous set of gems. Sorry that this isn't so helpful...

tobogranyte
  • 899
  • 1
  • 9
  • 26
  • Are your `attr_accessors` fields in the db? – DickieBoy Mar 24 '15 at 16:57
  • No. They're not. But I figured out the answer (see my answer below and my final update). Rails 4.0.2 didn't seem to be handling things correctly. I upgraded to 4.1.8 and like magic, everything just worked correctly. – tobogranyte Mar 24 '15 at 17:31
  • You have solved the problem yes. But the why of the problem (i believe) is still unconfirmed, I can't believe it was a problem with the version of Rails. – DickieBoy Mar 24 '15 at 17:56
  • Is there anything you can see that might have caused the issue? – tobogranyte Mar 24 '15 at 18:15
  • The inclusion of `donation_items_attributes` in your `attr_accessor` seems suspicious, possibly overwriting the setter that the `accepts_nested_attributes` defines. – DickieBoy Mar 24 '15 at 18:20
  • I had the same thought myself, and got rid of it (before updating Rails). Made no difference. – tobogranyte Mar 24 '15 at 18:24
  • Also, while I'm far from an expert on this, I did spend a good deal of time slogging though many, many posts/articles etc. concerning strong parameters and the removal of attr_accessible from Rails. From what I can tell, it was only with Rails 4 that strong parameters became an integral part of the platform. It had previously been a [gem](http://richonrails.com/articles/rails-4-preview-strong-parameters). So it actually wouldn't surprise me if there were cases in such an early version of Rails 4 that there were some lingering issues with it. – tobogranyte Mar 24 '15 at 18:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/73689/discussion-between-tobogranyte-and-dickieboy). – tobogranyte Mar 24 '15 at 18:32

2 Answers2

0

From Rails Validations guide

presence This helper validates that the specified attributes are not empty. It uses the blank? method to check if the value is either nil or a blank string, that is, a string that is either empty or consists of whitespace.

You are requiring donation_item to be present, but your resulting params hash clearly has donation names blank, validation is failing. Calling save! when debugging these things can be helpful since it would throw a error on failure.

Dr.Strangelove
  • 1,505
  • 1
  • 11
  • 12
  • Actually, the (subsequent) save does not throw an error. It simply saves the MaterialDonationRequest and doesn't even attempt to save anything else, because for whatever reason, the association is never created in the first place. – tobogranyte Mar 23 '15 at 18:04
  • Meant to say "the associated donation_items are never created in the first place." – tobogranyte Mar 23 '15 at 18:19
0

I figured out the answer. In total desperation, I upgraded my Rails version from 4.0.2 which is what I had been using, to 4.1.8. After doing this, with no other changes whatsoever (except gem dependencies, of course), it just started working the way it's supposed to. So I guess Rails 4.0.2 has a problem with nested forms and strong parameters.

tobogranyte
  • 899
  • 1
  • 9
  • 26