【问题标题】:nested_form/cocoon: children not savingnested_form/cocoon:孩子不保存
【发布时间】:2014-05-11 23:23:43
【问题描述】:

在我的应用程序中,我有联系人,其中有很多目标(目标属于联系人)。我使用嵌套表单为两个模型创建/更新数据,但是在创建/更新操作期间只有第一个子目标被保存,这可以从下面传递的参数中看出:

Started PATCH "/contacts/2" for 127.0.0.1 at 2014-05-11 19:10:40 -0400
Processing by ContactsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"wKgOPegIJOFyrrLAnbdD67qqATFXrPNqMIT7I/tpNfo=", "contact"=>{"name"=>"Steven Tyler", "title"=>"Manager", "company"=>"Dell", "email"=>"steve@dell.com", "notes"=>"cool guy", "goals_attributes"=>{"0"=>{"title"=>"goal1", "due_date(1i)"=>"2014", "due_date(2i)"=>"5", "due_date(3i)"=>"11", "notes"=>"fdfsd", "_destroy"=>"false", "id"=>"13"}}}, "commit"=>"submit", "id"=>"2"}
  Contact Load (0.1ms)  SELECT  "contacts".* FROM "contacts"  WHERE "contacts"."id" = ? LIMIT 1  [["id", 2]]
   (0.1ms)  begin transaction
  Goal Load (0.3ms)  SELECT "goals".* FROM "goals"  WHERE "goals"."contact_id" = ? AND "goals"."id" IN (13)  [["contact_id", 2]]
   (0.1ms)  commit transaction
Redirected to http://localhost:3000/contacts/2

这是我的模型:

class Contact < ActiveRecord::Base

  belongs_to :user
  has_many :goals, dependent: :destroy
  accepts_nested_attributes_for :goals, allow_destroy: true, reject_if: lambda {|attributes| attributes['title'].blank? && attributes['notes'].blank?}
  validates_presence_of :user_id,:name,:title,:email
end

class Goal < ActiveRecord::Base

  belongs_to :contact
  validates_presence_of :title, :due_date
end

而且,Contacts 控制器中的强参数:

def contact_params
      params.require(:contact).permit(:name, :title, :company, :email, :notes, goals_attributes: [:title, :due_date, :notes, :contact_id, :_destroy, :id])
    end

这里是使用的两种形式:https://gist.github.com/nowgeez/5fbe99e814330c1b371c 知道为什么只保存第一个目标,而没有在表单中创建任何其他后续目标吗?在此先感谢您的帮助。

【问题讨论】:

  • 您能告诉我们表单是如何构建的吗?
  • @BrightBlue 为表单添加了要点。

标签: ruby-on-rails ruby-on-rails-4 nested-forms cocoon-gem


【解决方案1】:

如文档中所述,使用正确的 div 嵌套很重要。

所以在你的情况下你应该写:

<%= simple_form_for(@contact) do |f| %>

  <%= f.input :name %>
  <%= f.input :title %>
  <%= f.input :company %>
  <%= f.input :email %>
  <%= f.input :notes %>

  <h3>Goals:</h3>
  <div id="goals">
    <%= f.simple_fields_for(:goals) do |goal| %>
      <%= render 'goal_fields', :f => goal %>
    <% end %>  
    <div class="links">          
      <%= link_to_add_association 'add goal', f, :goals %>
    </div>
  </div>

  <%= f.submit :submit %>

<% end %>

为了清楚起见,我删除了错误块。 目标本身应该包含在一个 div 中,以便删除工作。

<div class="nested-fields>
  <%= f.input :title %>
  <%= f.input :due_date %>
  <%= f.input :notes %>

  <%= link_to_remove_association "remove goal", f %>
</div>

附带说明:我讨厌写 erb,它更冗长,从您的主旨来看,它似乎正确嵌套,但实际上并非如此。 Haml 更清楚。 为了证明我的观点,上面的haml形式看起来像:

= simple_form_for @contact do |f|
  = f.input :name
  = f.input :title
  = f.input :company
  = f.input :email
  = f.input :notes

  %h3 Goals
  #goals
    = f.simple_fields_for :goals do |goal|
      = render 'goal_fields', :f => goal
    .links
      = link_to_add_association 'add goal', f, :goals
  = f.submit

但我知道这是一个品味问题。

【讨论】:

  • 感谢您的回复!我今晚晚些时候会检查这个并接受答案。欣赏它。
  • 感谢您帮助指出问题。是的,Haml 看起来确实干净多了。一旦对 Rails 更加熟悉,我肯定会看到自己切换。谢谢。
【解决方案2】:

在您的请求中只有一个目标

"goals_attributes"=>{"0"=>{"title"=>"goal1", "due_date(1i)"=>"2014", "due_date(2i)"=>"5", "due_date(3i)"=>"11", "notes"=>"fdfsd", "_destroy"=>"false", "id"=>"13"}}}

我猜你用强参数做错了,把它改成这样:

def contact_params
  params.require(:contact)
  .permit(:name, :title, :email, :company, :notes,
   goal_attributes: [:title, :due_date, :notes, :_destroy, :id])
end

【讨论】:

  • 看起来我的参数(几乎)完全符合您的建议。我还尝试将我的更改为goals_attributes:与“goals_attributes”相反,这没有什么区别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
相关资源
最近更新 更多