【问题标题】:dynamic check_box using field_for in rails在 rails 中使用 field_for 的动态复选框
【发布时间】:2010-03-29 20:06:46
【问题描述】:

我与链接框有多对多的关系,我想将这些模型整合到一个表单中,这样我就可以从同一页面进行更新。我真的很难让 check_box 甚至显示我的数组的所有元素 - 我已经搜索了网络并且整天都在研究这个,我发现很难应用我正在阅读的信息我的问题。我对 RoR 也非常陌生,而且我一直在关注一些过时的视频教程(2.0 之前),所以为我的代码道歉。到目前为止,我已经让它只输出数组中的一个密钥对(最后一个) - 尽管在表单之外,教程中使用的代码完全按照它应该的方式工作。不过那用处不大! Host 是主要表单所针对的模型,而 Billing 是我试图添加到表单中的外部模型。

这是在教程中的表单之外工作的代码:

<% for billing in @billings -%>
<%= check_box_tag('billing_title[]', billing.id, @host.billings.collect
{|obj| obj.id}.include?(billing.id))%> <%= billing.title %><br />
<% end -%>

我只需要知道如何使它在表单中工作。这是前面提到的代码,它只在遍历它们后检索最后一个数组密钥对:

<% f.fields_for :billings do |obj| %><br />
<%= check_box_tag('billing_title[]', billing.id, @billings.collect
{|obj| obj.id}.include?(billing.id))%> <%= billing.title %><br />
<% end %>

调试(@billings):

--- 
- !ruby/object:Billing 
attributes: 
title: Every Month
id: "1"
attributes_cache: {}

- !ruby/object:Billing 
attributes: 
title: 12 Months
id: "2"
attributes_cache: {}

- !ruby/object:Billing 
attributes: 
title: 6 Months
id: "5"
attributes_cache: {}

非常感谢任何帮助。

【问题讨论】:

  • pastebin.com/Q4znSMyA 如果有帮助,这里有一个 pastebin

标签: ruby-on-rails checkbox dynamic fields-for


【解决方案1】:

Craig,听起来您正在寻找的是 accept_nested_attributes_for,这是一种处理表单中嵌套模型的更好方法。

与其偷走 Ryan 的所有作品并在这里重新发布,不如给你一个指向他的截屏视频的链接:

http://railscasts.com/episodes/196-nested-model-form-part-1

这是基于他的复杂表格系列。

您应该能够根据您想要做的事情定制本教程,但如果不是,我很乐意提供帮助。

编辑:

好的,在查看您的代码后,有几件事会导致您出现问题。 :)

首先,有了关联,你不需要为 billings 提取额外的集合,即:

@host = Host.find(params[:id])
@voips = Voip.find(:all)
@custsupps = Custsupp.find(:all)
@payments = Payment.find(:all)
@billings = Billing.find(:all) # <-- This is not needed and causing your problems

模型中的关联设置为您完成了这一切。这是rails的魔力的一部分。 :D

现在,重要的是要注意,在使用关联时,您需要确保对象实际上是关联的。换句话说,如果您的数据库中有 3 个 Billings 对象并且它们与您的 Host 对象没有关联,它们将不会显示在表单中。

如果您尝试使用复选框将帐单与主机相关联,您将需要采用不同的方法,因为您的表单仅显示与主机已关联的帐单。 p>

如果您只是想编辑或修改与主机关联的现有账单,例如,复选框代表“付费”属性(布尔值),那么这种方法很好,您的表单代码看起来像这样:

<% f.fields_for :billings do |b| %><br />
  <%= b.check_box :paid %> <%= b.title %>
<% end %>

所以也许从功能的角度澄清您试图完成的工作,我们可以找到更好的解决方案。

【讨论】:

  • 感谢尘土的回复!我实际上已经看过该教程并且已经在我的 Host 模型中放置了我的accepts_nested_attributes_for,目前我什至还没有进入提交表单的阶段 - 我可以将数组发送到表单页面,但我不能t 使用 field_for 函数构建我的复选框。它是一个正确的头痛!但我真的很感谢你在解决这个问题方面的帮助,我几乎要放弃 RoR 并回到 php,因为我已经在这方面工作了太久 - 但我真的想解决这个问题 - 我不喜欢退出 :) 我可以提供什么信息给你?
  • 你知道,我昨天一定是在方向盘上睡着了,我刚刚又看了一遍你的代码,发现了问题。 :D 我会尽快发布修复。
  • 这是一个有趣的点dustmoo - 所以我可以把它放在一个部分,它会工作一样吗?我可以将 fields_for 放在自己的循环中以创建复选框列表吗?感谢您的帮助!
  • 我很高兴它在某种程度上很明显,哈哈,这意味着它(理论上)不应该太难修复吗?这是整个后端中唯一需要此功能的页面,因此一旦完成,我就可以继续创建 :) 非常感谢您的帮助。
  • 大声笑.. 不太明显,我认为这只是您要完成的工作与 Rails 约定之间的脱节。 :) 阅读我的编辑,我们将从那里开始。 :)
【解决方案2】:

我不确定我的答案,但我会尝试...

<% f.fields_for :billings, @billings do |obj| %>
   # ...
<% end %>

【讨论】:

  • 感谢您的尝试 :) 虽然这给了我与我尝试过的方法完全相同的输出 - 实际上我在一天中尝试了很多变体(是的,我今天已经在这个问题上工作了大约 10 个小时啊!)再次欢呼:)
  • 是的,这个更新后的代码与我发布的代码相同 - 一个复选框(数组中的最后一个 - 6 个月) - 迷你屏幕抓取:i39.tinypic.com/xcvq6q.jpg
【解决方案3】:

在我看来这是 for 循环的问题...

在您的示例代码中,您循环通过 @billings(从您的控制器传递的一组 billings 对象),并调用当前的 billing

在您的表单代码中,您循环通过:billings(引用帐单ActiveRecords 的符号)并调用当前obj。然后,令人困惑的是,您的代码在 @billings.collect 函数中再次使用了变量名 obj...但这应该具有本地私有范围并且不会影响您的主循环,但很难看到。

无论如何,由于表单循环中的内容没有引用obj,因此它使用变量billing——循环时不会更改,但会保留它的最后一个值:最后一项从上一个循环!这解释了为什么您只看到最后一个标签。 (另外,debug(@billings) 函数自己循环遍历各种记录——它不在 fields_for 循环内。)

我将首先更改表单代码的第一行以再次使用变量名称billing,如下所示:

<% f.fields_for :billings do |billing| %><br />

Ruby's block syntax 一开始可能会让人很困惑——或者,见鬼,任何时候你在阅读不是你自己写的代码——但是当你把它分解成基本的组件时,它通常只是循环通过一个一组项目并在每个项目上执行一些功能。还要注意外观相似的名称之间的混淆:@billing、@billings、:billings 和 billings 对于 Ruby 和 Rails 来说都是不同的东西。祝你好运!

【讨论】:

  • 谢谢你 :) 我已经改变了你提到的那一行,现在我得到一个错误: undefined method `title' for #<:helpers::formbuilder:0x48a0c08> 这个必须与用于标记我的表单的 billing.title 相关: 虽然如果我完全删除标签,那么我(再次)只得到一个最后一个(这次未标记)复选框数组中的项。这一切都非常令人困惑,但我非常感谢您的帮助。我的意思是调试显示密钥对存在于 billings 数组中 - 我似乎无法遍历数组!再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
  • 2016-08-08
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多