本文介绍了Rails 5,Cocoon Gem-嵌套表格内的嵌套表格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用茧形宝石来构建嵌套表格.

I am trying to use cocoon gem to build nested forms.

我有用于Organisation,Package :: Bip和Tenor的模型.

I have models for Organisation, Package::Bip and Tenor.

关联是:

组织

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

Package :: Bip(多态)

Package::Bip (polymorphic)

 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(多态)

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

表格具有:

在我的组织/_form.html.erb中,我有:

In my organisations/_form.html.erb, I have:

<%= f.simple_fields_for :bips do |f| %>
      <%= f.error_notification %>
        <%= render 'package/bips/bip_fields', f: f %>

    <% end %>

    <%= link_to_add_association 'Add another intellectual property resource', f, :bips, partial: 'package/bips/bip_fields' %> 

在我的bip_fields.html.erb嵌套表格中,我有:

In my bip_fields.html.erb nested form, I have:

<%# if @package_bips.tenor.blank? %> 
  <%= link_to_add_association 'Add timing', f, :tenor, partial: 'tenors/tenor_fields' %>  
<%# end %>

<%= f.simple_fields_for :tenor do |tenor_form| %>
  <%= f.error_notification %>
    <%= render 'tenors/tenor_fields', f: tenor_form %>
<% end %> 

JavaScript

茧文档建议添加一个js文件以将association-insertion-node指定为函数.在我的tenor_subform.js中,我有:

The cocoon docs suggest adding a js file to specify association-insertion-node as a function. In my tenor_subform.js I have:

$(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')
      });
});

控制器

在我的组织控制器中,我有:

In my organisation controller, I have:

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

注意:我不确定是否需要在我的新操作中添加另一行来创建Organisation.bip.tenor实例.我也不确定我是否应该通过引用该男高音的Organisation.rb上的关联来添加has_one.

Note: I'm not sure if I need to add another line to my new action to create the organisation.bip.tenor instance. I'm also unsure if im supposed to add has_one through association on the organisation.rb that references the tenor.

def organisation_params
      params.fetch(:organisation, {}).permit(:title,  :comment,

          bips_attributes:            [:id, :status,  :_destroy,
            tenor_attributes:           [:id,:commencement, :expiry,                      :_destroy]

        ],

在我的男高音控制器中,我有:

In my tenor controller, I have:

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

错误

我不确定是否需要向组织控制者(bip的最终父级,而bip的父级)添加男高音动作.

I am not sure if I need to add tenor actions to the organisation controller (the ultimate parent of bip which in turn is the parent of tenor).

保存所有内容并尝试使用时,出现错误消息:

When I save all of this and try it, I get an error that says:

unknown attribute 'tenor_id' for Tenor.

当我看到其他带有此错误的SO帖子时,通常是因为:id属性尚未在父类中列入白名单.我已经做到了.

When I see other SO posts with this error, its often because the :id attribute hasn't been whitelisted in the parent class. I have done that.

有人能看到我做错了吗?

Can anyone see what I've done wrong?

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

推荐答案

您错误地声明了has_one关系.因为您说as: :tenor使其寻找tenor_id.

You has_one relation is wrongly declared. Because you say as: :tenor makes it look for a tenor_id.

您必须声明如下:

has_one :tenor, as: :tenorable 

这篇关于Rails 5,Cocoon Gem-嵌套表格内的嵌套表格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 14:19