【问题标题】:Rails nested form with cocoon. Attributes using model带有茧的 Rails 嵌套形式。使用模型的属性
【发布时间】:2017-01-09 22:01:46
【问题描述】:

我正在尝试创建一个嵌套表单,其中包含选项和子选项,两者都来自名为 Option 的同一模型。以下是文件内容:

型号:

class Option < ApplicationRecord
  belongs_to :activity
  has_many :option_students
  has_many :students, through: :option_students

  has_many :suboptions,
    class_name: "Option",
    foreign_key: "option_id"

  belongs_to :parent,
    class_name: "Option",
    optional: true,
    foreign_key: "option_id"

  accepts_nested_attributes_for :suboptions,

    reject_if: ->(attrs) { attrs['name'].blank? }

  validates :name, presence: true
end

控制器:

class OptionsController < ApplicationController
  include StrongParamsHolder

  def index
    @options = Option.where(option_id: nil)
  end

  def show
    @option = Option.find(params[:id])
  end

  def new
    @option = Option.new()
    1.times { @option.suboptions.build}
  end

  def create
    @option = Option.new(option_params)
    if @option.save
      redirect_to options_path
    else
      render :new
    end
  end

  def edit
    @option = Option.find(params[:id])
  end

  def update
    @option = Option.find(params[:id])
    if @option.update_attributes(option_params)
      redirect_to options_path(@option.id)
    else
      render :edit
    end
  end

  def destroy
    @option = Option.find(params[:id])
    @option.destroy
    redirect_to options_path
  end

end

_form.html.erb:

<%= form_for @option do |f| %>

  <p>
    <%= f.label :name %><br>
    <%= f.text_field :name %><br>
    <%= f.label :activity %><br>
    <%= select_tag "option[activity_id]", options_for_select(activity_array) %><br>
  </p>

  <div>
    <div id="suboptions">
      <%= f.fields_for :suboptions do |suboption| %>
        <%= render 'suboption_fields', f: suboption %>
      <% end %>

      <div class="links">
        <%= link_to_add_association 'add suboption', f, :suboptions %>
      </div>
    </div>
  </div>

  <p>
    <%= f.submit "Send" %>
  </p>
<% end %>

_suboption_fields.html.erb

<div class="nested-fields">
  <%= f.label :suboption %><br>
  <%= f.text_field :name %>
  <%= link_to_remove_association "X", f %>
</div>

StrongParamsHolder:

def option_params
    params.require(:option).permit(:name, :activity_id, :students_ids => [], suboptions_attributes: [:id, :name])
end

视图已正确创建,但未保存。它在创建控制器上“渲染:新”。我认为这应该是参数的问题,但我不确定是什么。

【问题讨论】:

    标签: ruby-on-rails nested-forms has-many belongs-to cocoon-gem


    【解决方案1】:

    可能由于验证失败而无法保存。如果您使用的是 rails 5,belongs_to 现在更加严格,并且为了能够保存嵌套参数,您需要明确关联之间的连接/关系。

    所以恕我直言,如果您将inverse_of 添加到您的关系中,如下所示:

    has_many :suboptions,
      class_name: "Option",
      foreign_key: "option_id",
      inverse_of: :parent 
    
    belongs_to :parent,
      class_name: "Option",
      optional: true,
      foreign_key: "option_id"
      inverse_of: :suboptions
    

    如果另一个验证失败,它也可能有助于在您的表单中列出错误(例如,@option.errors.full_messages.inspect 之类的内容会有所帮助:)

    顺便说一句:我会将数据库中的option_id 字段重命名为parent_id,因为这更清楚地传达了它的含义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-17
      相关资源
      最近更新 更多