Paul Hulme
Paul Hulme

Reputation: 93

Rails 4: Create new records through has_many association

I am trying to create a new record for 'campaign' via the 'customer' as follows. The form submits correctly, however no new campaign record is created for the customer. Any advise would be greatly appreciated.

Models

class Customer::Customer < User
  has_one :library, dependent: :destroy
  has_many :campaigns, dependent: :destroy
  accepts_nested_attributes_for :campaigns, :library,  allow_destroy: true
end

class Customer::Campaign < ActiveRecord::Base
  belongs_to :customer
end

Customer Controller - Update Method only shown

class Customer::CustomersController < ApplicationController
  layout "customer_layout"
  def update
    session[:return_to] ||= request.referer
    @customer = User.find(params[:id])
    if @customer.update_attributes(customer_params)
      flash[:success] = "Profile updated"
      redirect_to @customer
    else
      flash[:notice] = "Invalid"
      redirect_to session.delete(:return_to)
    end
  end

  def customer_params
    params.require('customer_customer').permit(:name, :email, :password, :password_confirmation, :country_code, :state_code, :postcode, :first_name, :surname, campaigns_attributes:[:name, :description, :start_date, :complete_date ])
  end
end

And the form I am using

<%= form_for @customer do |f| %>
  <%= render 'shared/customer_error_messages' %>
  <%= f.fields_for :campaign do |builder| %>
    <%= builder.label :name, "Campaign Name" %></br>
    <%= builder.text_field :name %>
  <% end %>
  <div class="actions">
    <%= f.submit class: "btn btn-large btn-primary"%>
  </div>
<% end %>

And the console output (with error, is as follows)

Started PATCH "/customer/customers/38" for 127.0.0.1 at 2014-05-26 23:13:10 +1000
Processing by Customer::CustomersController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"9ChLYna0/VfZSMJOa2yGgvWTT61XkjoYwlVup/Pbbeg=", "customer_customer"=>{"campaign"=>{"name"=>"My new campaign"}}, "commit"=>"Update Customer", "id"=>"38"}
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '0e8b4ba6dc957e76948fc22bae57673404deb9fe' LIMIT 1
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", "38"]]
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", "38"]]
Unpermitted parameters: campaign

Upvotes: 3

Views: 2018

Answers (1)

Alexander Kireyev
Alexander Kireyev

Reputation: 10825

If this form performs adding only one campaign i guess you should handly add this exect campaign to customer. If you update all campaign model in such way, you should have all your campaigns in array. So it implies another controller action for this.

Another way: to check if params contains field campain and then just add it to customer object:

def update
  session[:return_to] ||= request.referer
  @customer = User.find(params[:id])

  if new_campaign_customer_params.has_key? :campaign
    @customer.campaigns << Campaign.new(new_campaign_customer_params)
    if @customer.save
      flash[:success] = "Profile updated"
      redirect_to @customer
    else
      flash[:notice] = "Invalid"
      # you should rerender your view here, set it path
      render 'your_view'
    end
  else
    if @customer.update_attributes(customer_params)
      flash[:success] = "Profile updated"
      redirect_to @customer
    else
      flash[:notice] = "Invalid"
      redirect_to session.delete(:return_to)
    end
  end
end

def new_campaign_customer_params
  params.require('customer_customer').permit(campaign_attributes:[:name, :description, :start_date, :complete_date ])
end

Check this out, not sure it works.

Or maybe it would work how to suggests in comment: change campaigns_attributes => campaign_attributes in customer_params method, and f.fields_for :campaigns in form (belongs to @Nikita Chernov)

Upvotes: 2

Related Questions