Rails 5, Cocoon Gem: forma anidada dentro de forma anidada

Estoy tratando de usar la gem de capullo para construir formas anidadas.

Tengo modelos para Organización, Paquete :: Bip y Tenor.

Las asociaciones son:

Organización

has_many :bips, as: :ipable, class_name: Package::Bip accepts_nested_attributes_for :bips, reject_if: :all_blank, allow_destroy: true 

Paquete :: Bip (polimorfo)

  belongs_to :ipable, :polymorphic => true, optional: true, inverse_of: :bip has_one :tenor, as: :tenor accepts_nested_attributes_for :tenor, reject_if: :all_blank, allow_destroy: true 

Tenor (polimorfo)

 belongs_to :tenorable, :polymorphic => true, optional: true 

Los formularios tienen:

En mis organizaciones / _form.html.erb, tengo:

      

En mi formulario nested bip_fields.html.erb, tengo:

        

Javascript

Los documentos de Cocoon sugieren agregar un archivo js para especificar el nodo de inserción de asociación como una función. En mi tenor_subform.js tengo:

 $(document).ready(function() { $(".add_tenor a"). data("association-insertion-method", 'append'). data("association-insertion-node", function(link){ return link.closest('.row').next('.row').find('.tenor_form') }); }); 

Controladores

En el controlador de mi organización, tengo:

 def new @organisation = Organisation.new @organisation.bips end 

Nota : no estoy seguro de si necesito agregar otra línea a mi nueva acción para crear la instancia de organisation.bip.tenor. Tampoco estoy seguro de si debo agregar has_one a través de la asociación en organisation.rb que hace referencia al tenor.

 def organisation_params params.fetch(:organisation, {}).permit(:title, :comment, bips_attributes: [:id, :status, :_destroy, tenor_attributes: [:id,:commencement, :expiry, :_destroy] ], 

En mi controlador de tenor, tengo:

 def tenor_params params.require(:tenor).permit( :commencement, :expiry) end 

ERRORES

No estoy seguro de si necesito agregar acciones de tenor al controlador de la organización (el principal padre de bip, que a su vez es el padre del tenor).

Cuando guardo todo esto y lo bash, aparece un error que dice:

 unknown attribute 'tenor_id' for Tenor. 

Cuando veo otras publicaciones de SO con este error, a menudo se debe a que el atributo: id no se ha incluido en la lista blanca de la clase principal. Ya lo he hecho.

¿Alguien puede ver lo que he hecho mal?

Controlador de tenor

 class TenorsController < ApplicationController before_action :set_tenor, only: [:show, :edit, :update, :destroy] before_action :authenticate_user! # after_action :verify_authorized def index @tenors = Tenor.all # authorize @tenors end def show end def new @tenor = Tenor.new # authorize @tenor end def edit end def create @tenor = Tenor.new(tenor_params) # authorize @tenor respond_to do |format| if @tenor.save format.html { redirect_to @tenor } format.json { render :show, status: :created, location: @tenor } else format.html { render :new } format.json { render json: @tenor.errors, status: :unprocessable_entity } end end end def update respond_to do |format| if @tenor.update(tenor_params) format.html { redirect_to @tenor } format.json { render :show, status: :ok, location: @tenor } else format.html { render :edit } format.json { render json: @tenor.errors, status: :unprocessable_entity } end end end def destroy @tenor.destroy respond_to do |format| format.html { redirect_to action: :index } format.json { head :no_content } end end private def set_tenor @tenor = Tenor.find(params[:id]) # authorize @tenor end def tenor_params params.require(:tenor).permit(:express_interest, :commencement, :expiry, :enduring, :repeat, :frequency) end end 

Tu relación ha sido declarada erróneamente. Porque dices as: :tenor hace que busque un tenor_id .

Tienes que declararlo de la siguiente manera:

 has_one :tenor, as: :tenorable 

Su modelo no ve el id de nested_attr.Add :inverse_of => #{model} .

Ejemplo:

 class Tenor < ActiveRecord::Base has_many :traps, :inverse_of => :bips end 

Para más información mira esto o esta documentación.