Search code examples
ruby-on-railsnested-attributes

Trying to save to Parent and child tables in Rails, but get argument error on nested Attributes


Hi I am trying to save to two tables at the same time from one form. I have created Contact with a has_many relationship to Order which belongs_to Contact.

models/contact.rb

class Contact < ActiveRecord::Base
  has_many :orders
  accepts_nested_attributes_for :orders,  reject_if: :all_blank
end

models/order.rb

class Order < ActiveRecord::Base
  belongs_to :contact
end

I have also created the OrdersController which looks as follows

controllers/OrdersController.rb

    class OrdersController < ApplicationController
     def new    
        @contact = Contact.new
        @contact.orders.build
     end

    def create
        @contact = Contact.new(order_params)
        if @contact.save
            @order = @contact.orders.build(order_params)
            @order.save
            flash[:success] = "Your has been sent we'll get back to you shortly"
            redirect_to new_order_path
        else
            flash[:danger] = "We were unable to process your request please try again or email [email protected]"
            redirect_to new_order_path
        end
    end

    . . . 
    private 
        def order_params
            params.require(:contact).permit(:id,:name,:surname, :email, :comments, :dob, :phone_number, :contact_method, orders_attributes: [:email, :contact_id,:package,:jobs_strategy,:fast_turn_around,:order_comments, :contact_email])
        end
end

When I try and create and an order I get an error unknown attribute: name

    @contact = Contact.new(order_params)
    if @contact.save
        *** @order = @contact.orders.build(order_params) *** This is the line with the error
        @ordar.save
        flash[:success] = "Your has been sent we'll get back to you shortly"
        redirect_to new_order_path

Name does not exist in the Orders table which why I assume it is complaining, but it does exist in the Contacts table. Should I be creating this differently?

I have also tried @order = @contact.orders.create(order_params) with the same error.

Here is an sample of the view

  <%= form_for @contact, url: orders_path do |f| %>

        <div>
            <%= f.label :name %>
            <%= f.text_field :name, class:"form-control" %>
        </div>
        <div> 
.....
  <%= f.fields_for :order do |order| %>
       <div> 
            <%= order.label :package %>
            <%= order.text_field :package, class: "form-control" %>
        </div>

Solution

  • 1) First point is the create method has @ordar.save instead of @order.save which I am assuming as Typo

    2) The second point is @order = @contact.orders.build(order_params) this line does not require order_params and should be simply @order = @contact.orders.build

    So with those changes your create action should be,

    def create
        @contact = Contact.new(order_params)
        if @contact.save
    
            flash[:success] = "Your has been sent we'll get back to you shortly"
            redirect_to new_order_path
        else
            flash[:danger] = "We were unable to process your request please try again or email [email protected]"
            redirect_to new_order_path
        end
    end