【问题标题】:update join table has_many through with additional checkboxes通过附加复选框更新连接表 has_many
【发布时间】:2016-05-30 12:39:42
【问题描述】:

如果我在这里找不到解决方案,我不知道我应该去哪里寻找......

我知道有正确、简单的解决方案……但我就是不明白。

我有 3 个模型...

方案.rb

class Scheme < ActiveRecord::Base
  has_many :projects
  has_many :custom_issue_field_definitions, through: :scheme_custom_issue_field_definitions
  has_many :scheme_custom_issue_field_definitions
end

CustomIssueFieldDefinition.rb

class CustomIssueFieldDefinition < ActiveRecord::Base
  has_many :schemes, through: :scheme_custom_issue_field_definitions
  has_many :scheme_custom_issue_field_definitions
  belongs_to :custom_issue_field
end

SchemeCustomIssueFieldDefinition.rb

class SchemeCustomIssueFieldDefinition < ActiveRecord::Base
  belongs_to :scheme
  belongs_to :custom_issue_field_definition
end

加入模型有 3 个附加字段...类型:布尔值。


我想更新 scheme_custom_issue_field_definitions 表。控制器和表单应该是什么样子?

附加图片:

更新:

在控制台中我可以这样更新它:

a = Scheme.first
b = CustomIssueFieldDefinition.first
c = a.scheme_custom_issue_field_defintitions.find_or_create_by(custom_issue_field_definition: b)
c.update_attributes(visible: 1, reportable: 0, required: 0)

下次更新:

现在表格看起来像这样(完全错误):

<%= simple_form_for @scheme_new_custom_issue_field, url: configurations_scheme_path(@scheme), method: :put do |f| %>
      <% @available_custom_issue_field_definitions.each do |custom_issue_field| %>
        <tr>
            <td><%= custom_issue_field.label %></td>
            <td><%= f.input :visible, as: :boolean %></td>
            <td><%= f.input :reportable, as: :boolean %></td>
            <td><%= f.input :required, as: :boolean %></td>
        </tr>
      <% end %>
      <%= f.button :submit, class: "btn btn-primary" %>
    <% end %> 

和schemes_controller

def update
    @scheme = Scheme.find(params[:id])
    @scheme_new_custom_issue_field = @scheme.scheme_custom_issue_field_definitions.
      find_or_create_by(scheme_id: @scheme, custom_issue_field_definition_id: params[:custom_issue_field_definition_id])
    if @scheme_new_custom_issue_field.update_attributes(scheme_custom_issue_field_definition_params)
      flash[:success] = "Scheme has been successfully updated"
      redirect_to :back
    else
      render :edit
    end
  end

更新解决方案:

【问题讨论】:

  • 您使用的 Db 可视化工具是什么?只是好奇
  • 它的 MySql 工作台

标签: mysql ruby-on-rails ruby-on-rails-4 simple-form


【解决方案1】:

如果您想在控制台中创建新的SchemCustomIssueFieldDefinition 记录,我建议您使用这种替代方法:

a = Scheme.first
b = CustomIssueFieldDefinition.first
c = SchemeCustomIssueFieldDefinition.find_or_initialize_by(scheme: a, custom_issue_field_definition: b)
c.assign_attributes(visible: 1, reportable: 0, required: 0)
c.save

这将比您当前的示例代码少一个查询,因为它没有 UPDATE sql。

对于您的表单:

<%= simple_form_for @scheme, method: :patch do |f| %>
  <% @available_custom_issue_field_definitions.each do |custom_issue_field| %>
    <tr> 
      <%= f.simple_fields_for :scheme_custom_issue_field_definitions, @scheme.scheme_custom_issue_field_definitions.find_or_initialize_by(custom_issue_field_definition: custom_issue_field) do |ff| %>
        <%= ff.hidden_field :id %>
        <%= ff.hidden_field :scheme_id, value: @scheme.id %>
        <%= ff.hidden_field :custom_issue_field_definition_id, value: custom_issue_field.id %>
        <td><%= custom_issue_field.label %></td>
        <td><%= ff.input :visible, as: :boolean %></td>
        <td><%= ff.input :reportable, as: :boolean %></td>
        <td><%= ff.input :required, as: :boolean %></td>
      <% end %>
    </tr>
  <% end %>
  <%= f.button :submit, class: "btn btn-primary" %>
<% end %>

schemes_controller.rb:

class SchemesController < ApplicationController
  # ...
  def update
    @scheme = Scheme.find(params[:id])
    if @scheme.update(scheme_params)
      flash[:success] = "Scheme has been successfully updated"
      redirect_to :back
    else
     render :edit
    end
  end

  # ...

  private

  def scheme_params
    # update below if you need other scheme attributes to be updated
    params.require(:scheme).permit(:id, scheme_custom_issue_field_definitions_attributes: [:id, :scheme_id, :custom_issue_field_definition_id, :visible, :reportable, :required])
  end
end

方案.rb

class Scheme < ActiveRecord::Base
  # ...
  accepts_nested_attributes_for :scheme_custom_issue_field_definitions_attributes
  # ...
end

【讨论】:

  • 嗯...我已经检查了答案...但是出了点问题...不要忘记我想在适当的记录上保存可见...所以“可见”必须知道它想在哪里得救。 ff.input :visible给我错误的输出
  • 是的,我在上面表格中的回答中的“可见”属性与“scheme_custom_issue_field_definition”类型的记录相关联。您正在其中为您指定的每个 @available_custom_issue_field_definitions 创建/更新多个“scheme_custom_issue_field_definition”记录。这意味着您可以选中/取消选中表单中的“可见”属性,并且它将指向的记录是@scheme -> scheme_custom_issue_field_definitions。这就是fields_for 的用途(它为关联的记录构建表单元素)。错误是什么?
  • 你说so "visible" have to know where it want to be saved,但是是的可见已经知道它想要保存在哪里(如果记录存在/如果不存在则创建一个)。请参阅上面我的答案中的这一行:&lt;%= f.simple_form_for :scheme_custom_issue_field_definitions, @scheme.scheme_custom_issue_field_definitions.find_or_initialize(custom_issue_field_definition: custom_issue_field) do |ff| %&gt; 它会查找已创建的记录,如果不存在则对其进行初始化。
  • 哦,我现在知道了。我的表格中有一个错字。看到我上面更新的答案应该是 f.simple_fields_for 而不是 f.simple_form_for
  • hmm 现在看起来好多了...(我不明白你为什么将表格放入表格中)...但现在我有错误:undefined method find_or_initialize' for #<:activerecord_associations_collectionproxy:0x007fee3246d5c0>`
猜你喜欢
  • 2018-03-03
  • 1970-01-01
  • 2015-05-06
  • 2015-12-02
  • 2019-01-26
  • 2015-09-09
  • 2017-06-10
  • 1970-01-01
  • 2015-08-22
相关资源
最近更新 更多