I have this one to many relationship:
class Programa < ActiveRecord::Base
attr_accessible :descripcion, :nombre, :roles_attributes
has_many :roles, :dependent => :restrict
accepts_nested_attributes_for :roles
...
end
class Role < ActiveRecord::Base
attr_accessible :description, :name, :programa_id
belongs_to :programa
...
end
It works in rails console:
> params = { programa: { nombre: 'nuevo', roles_attributes: [ {name: 'role1'}, {name: 'role2'}] }}
> p = Programa.create(params[:programa])
> p
=> #<Programa id: 7, nombre: "nuevo", descripcion: nil, created_at: "2013-10-09 14:07:46", updated_at: "2013-10-09 14:07:46">
> p.roles
=> [#<Role id: 15, name: "role1", description: nil, created_at: "2013-10-09 14:07:46", updated_at: "2013-10-09 14:07:46", programa_id: 7>, #<Role id: 16, name: "role2", description: nil, created_at: "2013-10-09 14:07:46", updated_at: "2013-10-09 14:07:46", programa_id: 7>]
But I can not make it work in the app/views/programas/_form:
<%= form_for(@programa) do |f| %>
<%= render 'shared/form_error_messages', object: f.object %>
<div class="field">
<%= f.label :nombre %>
<%= f.text_field :nombre %>
</div>
<div class="field">
<%= f.label :descripcion %>
<%= f.text_field :descripcion %>
</div>
<% f.fields_for :roles do |builder| %>
<div class="field">
<%= builder.label :name %>
<%= builder.text_field :name %>
</div>
<div class="field">
<%= builder.label :description %>
<%= builder.text_field :description %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Is there anything else that I have to add or remove to make my form shows the roles nested attributes?
This is my the controller for programas:
class ProgramasController < ApplicationController
# GET /programas
# GET /programas.json
def index
@programas = Programa.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @programas }
end
end
# GET /programas/1
# GET /programas/1.json
def show
@programa = Programa.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @programa }
end
end
# GET /programas/new
# GET /programas/new.json
def new
@programa = Programa.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @programa }
end
end
# GET /programas/1/edit
def edit
@programa = Programa.find(params[:id])
end
# POST /programas
# POST /programas.json
def create
@programa = Programa.new(params[:programa])
respond_to do |format|
if @programa.save
format.html { redirect_to @programa, notice: 'Programa was successfully created.' }
format.json { render json: @programa, status: :created, location: @programa }
else
format.html { render action: "new" }
format.json { render json: @programa.errors, status: :unprocessable_entity }
end
end
end
# PUT /programas/1
# PUT /programas/1.json
def update
@programa = Programa.find(params[:id])
respond_to do |format|
if @programa.update_attributes(params[:programa])
format.html { redirect_to @programa, notice: 'Programa was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @programa.errors, status: :unprocessable_entity }
end
end
end
# DELETE /programas/1
# DELETE /programas/1.json
def destroy
@programa = Programa.find(params[:id])
@programa.destroy
respond_to do |format|
format.html { redirect_to programas_url }
format.json { head :no_content }
end
end
end
I just want the nested attributes to be shown in the edit and show actions only.
The form for the nested attributes will only show if there is actually data to show, ie. if your Programa instance has one or more Roles associated with it.
This can be as simple as @programa.roles.build
in your controller, before rendering the form, to add a new Role. Any existing roles will be rendered.
edit: You also need to actually render the form, ie. <%= f.fields_for
(note missing =
).