【问题标题】:Fields_for without a do loopFields_for 没有 do 循环
【发布时间】:2015-11-09 10:22:24
【问题描述】:

有没有办法在不循环所有关联项的情况下进行fields_forhas_many 关联?


我的情况与here讨论的情况非常相似:

我有一个Person 模型,有几个相关模型(AddressPhone numberJobtitle...),我只想在表单上创建新记录。 新记录应从现有记录中预先填写。我有一个辅助函数可以捕获正确的数据,我只想让fields_for 显示它而无需通过 do 循环。

【问题讨论】:

  • 你在说什么“循环”?
  • 可能循环浏览现有数据:/
  • <%= f.fields_for :addresses do |a| %> 枚举该人的所有地址。我不想那样做,我已经在别处查询过数据了。

标签: ruby-on-rails simple-form fields-for


【解决方案1】:

这是你需要的:

#app/models/person.rb
class Person < ActiveRecord::Base
   has_many :addresses
   has_many :phone_numbers
   has_many :job_titles

   accepts_nested_attributes_for :addresses, :phone_numbers, :job_titles
end

#app/controllers/people_controller.rb
class PeopleController < ApplicationController
   def edit
       @person = Person.find params[:id]
       @person.addresses.build #-> this adds onto the existing "addresses" for that person
   end
end

这将允许您使用以下内容:

#app/views/people/edit.html.erb
<%= form_for @person do |f| %>
   <%= f.fields_for :addresses do |a| %>
       <% if a.object.new_record? %>
          <%= a.text_field :street %>
          <%= a.text_field :town %>
       <% end %>
   <% end %>
   <%= f.submit %>
<% end %>

这应该只输出new 关联对象(您构建的对象)的输入。这有点 hacky,但我明白了你的问题 - 你想显示新的输入(现有的不应该显示)。

保存它会将关联记录添加到您的Person 对象。现有的仍然存在。

【讨论】:

  • 这基本上就是我正在做的事情,尽管我发现使用a.object.new_record? 并不适用于所有情况,并且如果验证失败,会在表单往返期间清除数据。我将正确的数据选择到一个名为 data_object 的变量中,然后检查a.object.attributes == data_object.attributes。这是我要删除的“循环”行为。
  • 你的意思是你想保持你的代码精简,从而删除循环功能,使其扫描已经分配的属性?
  • 你已经准确地击中了头部。问题是在这个项目中 People 模型有 16 个关联,每个关联可能有 5 或 6 个历史记录。由于这个枚举,我的页面加载时间超过了 10 秒 :(
  • 事实证明,如果你有has_many :addresses关系,你就不能有has_one :new_address关系,因为@person.build_new_address会尝试更新最后的历史地址记录,改变它的PK并设置除其他外,它的 FK 为 NULL。
  • 请删除“if if a.object.new_record?”行中的“if”。除此之外,这正是我想要的 :-) 干杯
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 2016-07-20
  • 1970-01-01
相关资源
最近更新 更多