Ruby on rails 修改连接模型上的属性时,接受\u嵌套的\u属性\u

Ruby on rails 修改连接模型上的属性时,接受\u嵌套的\u属性\u,ruby-on-rails,nested-attributes,Ruby On Rails,Nested Attributes,简单地说,一个联系人可以有各种相关的时间窗口,这些时间窗口可能作为日程表处于活动状态,也可能不处于活动状态。也就是说: 型号 class Contact < ActiveRecord::Base has_many :schedules has_many :time_windows, :through => :schedules accepts_nested_attributes_for :schedules, :allow_destroy => true end

简单地说,一个联系人可以有各种相关的时间窗口,这些时间窗口可能作为日程表处于活动状态,也可能不处于活动状态。也就是说:

型号

class Contact < ActiveRecord::Base
  has_many :schedules
  has_many :time_windows, :through => :schedules
  accepts_nested_attributes_for :schedules, :allow_destroy => true
end

class TimeWindow < ActiveRecord::Base
  has_many :schedules
  has_many :contacts, :through => :schedules
end

class Schedule < ActiveRecord::Base
  belongs_to :contact
  belongs_to :time_window
end
控制器中的更新操作基本上是库存,除了处理另一个相关模型的另一个实例,我使用Advanced Rails Recipes book中的“Handling Multiple Models”(处理多个模型)示例进行了编码

据我所知,我认为上述措施应该奏效。但是,日程安排没有任何更新。这将显示在服务器日志中:

  [4;35;1mSchedule Update (0.2ms)[0m   [0mUPDATE `schedules` SET `updated_at` = '2010-09-30 20:39:49', `active` = 0 WHERE `id` = 42[0m
  [4;36;1mSchedule Update (0.1ms)[0m   [0;1mUPDATE `schedules` SET `updated_at` = '2010-09-30 20:39:49', `active` = 0 WHERE `id` = 44[0m
(NetBeans在输出中给了我那些愚蠢的“[0m]”,我不知道那里出了什么问题。)

SQL显示“活动”布尔字段在选中的位置被设置为0。如何使其正确设置活动位

作为后续行动,我将如何组织这项工作以彻底消除计划“连接”?我想我需要提交一个:_从表单中删除计划,但是当涉及复选框时,我将如何有条件地这样做


感谢您提供的任何帮助。Rails对我来说是一个巨大的课题,我想“正确”地完成它我离这里很近,但必须有一种方法来做到这一点——不仅是正确的——而且是优雅的。视图代码感觉太麻烦了,无法成为合适的Rails;-

我一直在尝试不同的方法来解决这个问题,我已经想出了这个方法,它基本上是有效的。唯一的问题是它无法处理没有“时间表”的问题对于每个“时间窗口”,表单都会呈现,我会得到一个禁用的复选框(以防止我尝试删除不存在的内容),但我没有办法将其添加回,没有它提交会抛出params散列(并导致Rails给我一个“Expected hash(get Array)”错误)



schedule.new_记录?%>

请注意,“schedules_attributes[]”数组将自动在HTML中的大括号内为您提供一个现有ID(这很好),但是_attributes散列在其他属性旁边需要一个“ID”,以便理解子散列

我在这里学到的一个重要教训是,“check_box_tag”方法(似乎)没有给我一个成对的隐藏字段,以便Rails在未检查的情况下进行解析。我本该预料到这一点。手动添加一个字段会造成混乱,这导致我最终放弃了“fields_for”方法,并在找到合适的语法之前尝试了许多化身,以获得我想要的结果


我意识到我的模型在这个设置中不太合适,所以我要改变它,但我离这个答案太近了,我想至少在我继续之前能够看到结尾。

我一直在尝试不同的方法来解决这个问题,我已经想出了这个方法,它很有效。大多数情况下。唯一的问题是没有它不能处理每个“时间窗口”都没有“时间表”的问题。表单将呈现,我将得到一个禁用的复选框(以防止我尝试删除不存在的内容),但我没有办法将其添加回,没有它提交会抛出params散列(并导致Rails给我一个“预期散列(得到数组)”错误)



schedule.new_记录?%>

请注意,“schedules_attributes[]”数组将自动在HTML中的大括号内为您提供一个现有ID(这很好),但是_attributes散列在其他属性旁边需要一个“ID”,以便理解子散列

我在这里学到的一个重要教训是,“check_box_tag”方法(似乎)没有给我一个成对的隐藏字段,以便Rails在未检查的情况下进行解析。我本该预料到这一点。手动添加一个字段会造成混乱,这导致我最终放弃了“fields_for”方法,并在找到合适的语法之前尝试了许多化身,以获得我想要的结果


我意识到我的模型在这个设置中不太合适,所以我要修改它,但我离这个答案太近了,我想在继续之前至少能看到结尾。

如果您使用accepts\u nested\u attributes\u for,我建议您使用fields\u for(),它将使视图代码更不脆弱!脆弱?脆弱?!Rails的整个概念都是脆弱的!一次错过了多重化,整个事情就结束了。-)我咬了一口子弹。这些“[0m”只是控制台的颜色格式化。NetBeans似乎不理解这一点,所以它只是在打印它们。你能描述一下你想在视图中看到什么吗?你的代码看起来很复杂,而且可能写得更简单,但我不明白你想要什么。如果你正在使用accepts_nested_attributes_,我建议使用looking开始使用fields_for(),它会让视图代码变得不那么脆弱!脆弱?脆弱?!Rails的整个想法都很脆弱!一次错过了复数,整个事情就结束了。-)我咬了一口子弹。这些“[0m”只是控制台的颜色格式化。NetBeans似乎不理解这一点,所以它只是在打印它们。您能描述一下您希望在视图中拥有什么吗?您的代码看起来非常复杂,而且可能编写得更简单,但我不理解您希望拥有什么。
Parameters: { "commit" => "Update", "contact" => {
  "group_ids" => ["2"], "enabled" => "1",
  "schedules_attributes" => [ { "time_window_id"=>"1", "id"=>"46"},
   { "time_window_id" => "2", "id" => "42", "active" => "on" },
   { "time_window_id" => "3", "id" => "43"},
   { "time_window_id" => "4", "id" => "44", "active" => "on"}],
  "last_name" => ... 
  [4;35;1mSchedule Update (0.2ms)[0m   [0mUPDATE `schedules` SET `updated_at` = '2010-09-30 20:39:49', `active` = 0 WHERE `id` = 42[0m
  [4;36;1mSchedule Update (0.1ms)[0m   [0;1mUPDATE `schedules` SET `updated_at` = '2010-09-30 20:39:49', `active` = 0 WHERE `id` = 44[0m
<% TimeWindow.all.each do |tw| %>
  <% schedule = Schedule.find_by_contact_id_and_time_window_id(@contact.id, tw.id)
     schedule ||= Schedule.new %>

<% f.fields_for "schedules_attributes[]", schedule do |sf| %>
  <p>
    <%= sf.label tw.description %>
    <%= sf.hidden_field :id %>
    <%= sf.check_box :_destroy, :disabled => schedule.new_record? %>
    <%= sf.check_box :active %>
  </p>
<% end %>

<% end %>