代码之家  ›  专栏  ›  技术社区  ›  Kiada

在Rails中使用field_的动态复选框

  •  1
  • Kiada  · 技术社区  · 14 年前

    我和一个链接框有多对多的关系,我想把这些模型放到一个表单中,这样我就可以从同一个页面进行更新。我真的很难让复选框显示我的数组中的所有元素-我已经搜索了网络,并且一整天都在做这个,我发现很难将我正在阅读的信息应用到我的问题上。我对ror也非常陌生,我一直在学习一些过时的视频教程(2.0之前的版本),所以对我的代码表示歉意。到目前为止,我已经让它只输出数组中的一个键对(最后一个键对),尽管在表单之外,本教程中使用的代码工作得非常准确。不过这没什么用!主机是主窗体所针对的模型,而计费是我试图添加到表单中的外部模型。

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

    <% 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: {}
    

    任何帮助都非常感谢。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Dustin M.    14 年前

    克雷格,听起来你要找的是接受嵌套的属性,这是一种更好的方式来处理表单中的嵌套模型。

    我不只是偷了瑞安的所有作品然后把它放在这里,我只会给你一个链接,链接到他的电影剧本:

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

    这是基于他的复杂形式系列。

    你应该能够泰勒这个教程,你想做什么,但如果不是,我很乐意帮助。

    编辑:

    好吧,在看了你的代码之后,有一些事情导致了你的问题。:)

    首先,在关联方面,您不需要额外收集账单,即:

    @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对象,并且它们与宿主对象没有关联,那么它们不会显示在表单中。

    如果您试图使用复选框将账单与主机关联,您将希望采用不同的方法,因为您的表单只显示账单 已关联 和你的主人在一起。

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

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

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

        2
  •  0
  •   Ju Nogueira    14 年前

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

    <% f.fields_for :billings, @billings do |obj| %>
       # ...
    <% end %>
    
        3
  •  0
  •   ewall    14 年前

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

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

    在表单代码中,您正在循环 :billings (符号表示账单活动记录)并调用当前记录 obj . 然后,令人困惑的是,您的代码重新使用了变量名 OBJ 再次在@billings.collect函数中…但这应该有局部的私有范围,不会影响主循环,但是很难一眼就能解释清楚。

    总之,因为表单循环中的内容没有引用 OBJ ,它使用的是变量 演员表 --循环通过时不会改变,但会保留它的最后一个值:前一个循环的最后一个项!这就解释了为什么你只看到最后一个标签。(还有) debug(@billings) 函数通过排序记录执行自己的循环——它不在字段“for do loop”中。)

    我将从更改表单代码的第一行开始重新使用变量名 演员表 同样,像这样:

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

    Ruby's block syntax 一开始可能很混乱——或者,见鬼,任何时候你读的代码都不是你自己写的——但是当你把它全部分解成基本的组件时,它通常只是循环通过一组项目并对每个项目执行一些功能。还要注意相似的名字之间的混淆:@billing,@billings,:billings和billings对于ruby和rails都是不同的。祝你好运!

    推荐文章