Rails form with nested attributes (accepts_nested_attributes_for)

I have this attitude to many:

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 the 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 get it to work in the application / 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 I have to add or remove in order to make my form that shows the roles of nested attributes?

This is my controller for programs:

 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 nested attributes to appear only in edit and display actions.

+6
source share
1 answer

The form for nested attributes will be displayed only if the data is actually displayed, i.e. if your instance of Programa has one or more roles associated with it.

It can be as simple as @programa.roles.build in your controller, before rendering the form, add a new role. Any existing roles will be displayed.

edit : you also need to render the form, i.e. <%= f.fields_for (note missing = ).

+6
source

Source: https://habr.com/ru/post/955584/


All Articles