【问题标题】:Rails nested_form with has_many without create additional columns in child's tableRails nested_form 与 has_many 没有在子表中创建额外的列
【发布时间】:2016-02-16 15:37:42
【问题描述】:

我正在使用

class Mother < ActiveRecord::Base
  has_many :boys
  accepts_nested_attributes_for :boys, reject_if: :all_blank, allow_destroy: true
end

class Boy < ActiveRecord::Base
  belongs_to :mother

  attr_accessor :mother_id
end

因为我无法修改 Boys 表的列。

现在我在 Rails 中创建嵌套表单,但是当我去拯救 Mother and Boys 时,它会说:

ActiveModel::MissingAttributeError - can't write unknown attribute `mother_id`:

这很正常,因为mother_id 列不存在。但是我不需要保存Mother模型,只需要保存我使用gem cocoon形式的许多男孩,然后立即删除我不再需要的mother。

如何绕过男孩表中不存在的列mother_id,只保存男孩的行而不引用“假”母亲?

在 Rails 中是否有一种方法可以创建一个表单,在该表单中我可以使用 Cocoon 之类的机制,但具有相同的模型实例而不是子实例,而无需明确“accepts_nested_attributes_for”?

【问题讨论】:

  • 这意味着你永远没有母亲?所以我认为母亲模型的存在是不必要的
  • 是的,但我不知道如何使用例如茧宝石来制作一个包含许多“行”的表格,这些“行”是我的假“母亲”的孩子。我可以在没有母亲模型的情况下在我的 form.html.erb 中构建相同的模型,并同时保存许多男孩模型,例如茧?
  • 为什么不只是添加模型保存它并在保存Boy 后在您的create 操作中删除母亲
  • 不,你不明白我的意思。
  • 您可以添加您的表单吗?所以我明白你想做什么?,因为我真的不明白你为什么需要一个母亲模型,你可以添加一个表单来创建男孩,就是这样......

标签: ruby-on-rails ruby-on-rails-4 activerecord rails-activerecord


【解决方案1】:

在您的情况下,完全不需要 Mother 模型,也不需要使用 cocoon,因为您不需要保存父模型。我要做的就是创建一个仅用于创建Boy 的表单,如果您希望它看起来像“嵌套”表单,那么您可以对其进行 Ajaxify 以使其具有嵌套的外观。

删除您的Mother 模型,您不需要它,然后为您的Boy 添加一组基本路由

routes.rb

resources :boys

boys_controller.rb

def create
        respond_to do |format|
            @boy = Boy.new boy_params
            @boy.save
            format.js
        end
end

_form.rb

#just make sure you have remote: true and check that you are always creating a new Boy
<%= form_for Boy.new, builder: yourBuilder, remote: true do |f| %>
.....
<% end %>

在您的视图中添加一个 div,您可以在其中显示您的男孩,并在以后每次创建新的时附加它们:

        <div id="boys">
            #Whatever collection you can get for show the current created boys I do not know, let's say current_user
            <% current_user.boys.each do |boy| %>
                <%= render boy %>
            <% end %>
        </div>

接下来只需为您的create 操作添加一个脚本:

男孩/create.js.erb

#If @boy is still not persisted it means it has errors, display errors
<% if @boy.new_record? %>
    $('#boy_form').append("<span class=\"error\"><%= j @boy.errors.full_messages.join(', ').html_safe %></span>");
    setTimeout(function() {
      $('#new_group_goal .error').remove();
    }, 8000);
<% else %>
   #Else we prepend the @boy in the div #boys and that's it, you form is beautifully ajaxified.
    $('#boys').prepend("<%= j render(@boy) %>");
    setTimeout(function() {
      $('# .error').remove();
    }, 2000);
<% end %>

通过这种方式,您可以使用 Ajax 创建 Boy 的统一表单,您可以动态添加男孩,它看起来像一个嵌套表单,而不是执行 1 个提交操作,而是执行提交以创建所有男孩,您将为每个男孩执行1个提交动作并在表单下方动态显示,这种方式更灵活,并且这种方式具有更好的性能。如果你明白我的意思,请告诉我。

【讨论】:

  • 这对我来说太难了。如何保存我的母亲模型忽略ActiveModel::MissingAttributeError - can't write unknown attribute mother_id: 错误?
  • 你不能那样做,你知道 Rails 使用 SQL 结构,SQL 不会让你保存没有 id 的关联...尝试实现我给你的最好的选择。
  • 但是我不能有一个带有像茧这样的按钮的列表来添加一行并在最后保存?
  • 我不明白你的解决方案。对不起。我被困住了。
  • 我已经为您提供了解决您的问题的方法,应该够了,我不能为您做更多,抱歉...
猜你喜欢
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 2013-01-05
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多