【问题标题】:Rails: radio button selection for nested objectsRails:嵌套对象的单选按钮选择
【发布时间】:2011-07-02 17:26:30
【问题描述】:

我被这个简单的选择任务困住了。我有这个模型:

#  id         :integer(4)      not null, primary key
#  category   :string(255)
#  content    :text
class Question < ActiveRecord::Base
    has_many :choices, :dependent => :destroy
    accepts_nested_attributes_for :choices
end

#  id          :integer(4)      not null, primary key
#  content     :text
#  correct     :boolean(1)
#  question_id :integer(4) 
class Choice < ActiveRecord::Base
    belongs_to :question
end

当我创建一个新问题时,我想以嵌套形式指定 Question 中的 content,甚至是 3 个 Answer 对象中的 content,然后使用单选按钮进行选择一个是correct 答案。在控制器的new 动作中,我有这个:

def new
    @title = "New Question"
    @question = Question.new
    3.times { @question.choices.build }

    respond_to do |format|
        format.html # new.html.erb
        format.xml  { render :xml => @question }
    end
end

这是表单代码:

<%= simple_form_for @question do |question_form| %>
    <%= question_form.error_notification %>

    <div class="inputs">
    <%= question_form.input :content, :label => 'Question' %>
    <%= question_form.input :category, :collection => get_categories, :include_blank => false %>

    <% @question.choices.each do |choice| %>
        <%= question_form.fields_for :choices, choice do |choice_fields| %>
            <%= choice_fields.input :content, :label => 'Choice' %>
            <%= choice_fields.radio_button :correct, true %>
            <%= choice_fields.label :correct, 'Correct Answer' %>
        <% end %>
    <% end %>
    </div>

    <div class="actions">
    <%= question_form.button :submit %>
    </div>
<% end %>

问题在于这段代码生成了三个名称不同的单选按钮:您可以选择多个正确答案,这不是正确的行为。三个单选按钮的名称是question[choices_attributes][0][correct]question[choices_attributes][1][correct]question[choices_attributes][2][correct]

问题是:如何创建三个具有相同名称的单选按钮,以便选择一个且只有一个正确答案?如何创建正确的params 数组,以便以这种方式将它们保存在create 操作中:

def create
    @question = Question.new(params[:question])
    # render or redirect stuff....
end

非常感谢!

【问题讨论】:

  • 我也有同样的问题,为什么没人帮忙回答? :(
  • 你找到答案了吗?把我的头发扯下来!

标签: ruby-on-rails-3 radio-button nested-forms nested-attributes


【解决方案1】:

您可以使用radio_button_tag 并将您自己的名称属性传递给它。

由于您仍在 choice_fields 范围内,因此您可以访问一些可以公开您正在处理的对象的方法,这将帮助您正确命名您的 radio_button_tag

以下代码将为您的单选按钮提供正确的名称,以作为嵌套属性接受:

&lt;%= radio_button_tag "question[choices_attributes][#{choice_fields.index}][correct]", true, choice_fields.object.correct %&gt;

choice_fields.index 使您可以访问正在创建的资源的正确索引,因此第一个 coice 将具有名称 question[choices_attributes][0][correct],第二个将具有名称 question[choices_attributes][1][correct],等等。

choice_fields.object.correct 让您可以访问当前值,以便为编辑表单填写正确的单选按钮。

更新: 上面的解决方案实际上是错误的,它为每个单选按钮提供了不同的name 属性,因此它们最终不会一起工作(您可以一次选择多个单选按钮)。

我最终采用的解决方案如下:

<%= radio_button_tag "question[choices_attributes][correct_choice]", choice_fields.index, choice_fields.object.correct %>

这为每个单选按钮提供了与其他单选按钮相同的名称,并且其值等于正确选择的索引。参数哈希最终看起来像这样:

question: {choices_attributes: {
        "0": {//choice 0},
        "1": {//choice 1},
        etc...
    },
    correct_choice: //index of correct answer
}

然后我更新了我的控制器以手动更新正确的选择,如下所示:

def create

    # Find the index of the correct choice in the params hash
    correct_index = params[:question][:correct_choice]

    # mark the question at the correct index as correct
    params[:question][:choiceses_attributes][correct_index][:correct] = true

    # Use the updated params hash to create a new Question/update an existing Question

    @question = Question.new(params[:question])
    # render or redirect stuff....
end

【讨论】:

  • 你能解释一下你的控制器吗?
  • 当然!我在控制器中添加了一些 cmets 以进行澄清。
  • 我想补充一点,我在 Rails 5.1.4 中遇到了类似的问题,我不得不调用 params.permit!在更新的参数被允许用于创建/保存之前。
【解决方案2】:

您可以将 name 选项传递给 radio_button 方法:

<%= choice_fields.radio_button :correct, true, :name => "choices_attributes" %>

(来自 rails 文档,http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html: radio_button(object_name, method, tag_value, options = {}) )

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    这是一个非答案,但我建议您尝试 Formtastic。它使处理像这样 STUPID EASY 的嵌套模型变得容易:https://github.com/justinfrench/formtastic

    【讨论】:

      【解决方案4】:

      这绝对适用于 Rails 4。没有检查其他版本:

      您的标签和单选字段应如下所示:

      <%= choice_fields.radio_button :correct, true %>
      <%= choice_fields.label :correct, value: true, do %>
        'True'
      <% end %>
      <%= choice_fields.radio_button :correct, false %>
      <%= choice_fields.radio_button :correct, value: false, do %>
        'False'
      <% end %>
      

      要让标签在点击时触发单选按钮,您必须在 &lt;%= choice_fields.label ... %&gt; 中有 value: whatever_your_value_is

      【讨论】:

        猜你喜欢
        • 2010-11-25
        • 1970-01-01
        • 2011-07-30
        • 1970-01-01
        • 2022-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多