Gustavo Rego
Gustavo Rego

Reputation: 335

Nested attributes with collection_select - Rails 4

When I press the submit button, it goes to my 'create' action and then saves the main object, but the foreign key is null as it has not been passed via post, here is my code:

Models:

class Ticket < ActiveRecord::Base
  belongs_to :system

  validates :title, presence: true, length: {minimum: 1, maximum: 60}

  accepts_nested_attributes_for :system
end

class System < ActiveRecord::Base
  has_many :tickets
  validates :name, presence: true, length: {minimum: 1, maximum: 50}
end

Controller:

class TicketsController < ApplicationController
  def new
    @system = System.actives
    @priority = Priority.actives
    @ticket = Ticket.new
    respond_to :js, :html
  end

  def create
    @ticket = Ticket.new(ticket_params)
    @ticket.save
    respond_with(@ticket)
  end

  def ticket_params
    params.require(:ticket).permit(:title, :active, systems_attributes: [:id,:name])
  end
end

View

<%= form_for @ticket, remote: true do |f| %>

  <div class="form-group">
    <%= f.label :Título %><br>
    <%= f.text_field :title, class: 'form-control' %>
  </div>

  <div class="form-group">
    <%= f.label :Sistema %><br>
    <%= f.fields_for :systems do |fs| %>
    <%= fs.collection_select :id,
      @system.order(:name),:id,:name, {include_blank: 'Selecione...'},
      {class: 'form-control', id: 'system_select'}%>
    <% end %>
  </div>

  <div class="actions">
    <%= f.submit "Abrir Chamado", class: "btn btn-info" %>
  </div>

<% end %>

So, it saves the ticket object with a title, but without a system_id, any helpful tip would be great here.

Upvotes: 0

Views: 455

Answers (2)

Pavan
Pavan

Reputation: 33542

There are few mistakes in your code.

Firstly,in your new action,you need to add this line @ticket.build_system

def new
  @system = System.actives
  @priority = Priority.actives
  @ticket = Ticket.new
  @ticket.build_system
  respond_to :js, :html
end

Your ticket_params method should be like this

def ticket_params
  params.require(:ticket).permit(:title, :active, system_id,system_attributes: [:id,:name])
end

Notice system_id and system_attributes.

And finally,you need to change this line <%= f.fields_for :systems do |fs| %> to <%= f.fields_for :system do |fs| %>

Upvotes: 1

Jake Shorty
Jake Shorty

Reputation: 727

I don't entirely understand your form, but in ticket_params it looks like you have the :id you want in the array value for systems_attributes. If that is indeed what you're trying to pass your new Ticket, then it needs to be passed differently within Ticket.new. The arguments/options hash you're passing to Ticket.new with ticket_params should be key-value pairs like so:

Ticket.new(title: "yourtitle", other: "whatever", system_id: "your_id")

I'd either change the output of ticket_params so that it passes your system_id in this way, or manually pass it in (keying it out of the parameters) within your create action.

Upvotes: 0

Related Questions