【问题标题】:Multiple radio buttons getting selected in Rails app在 Rails 应用程序中选择多个单选按钮
【发布时间】:2019-09-23 20:51:14
【问题描述】:

我有一个应用程序,其中Question 模型has_manyOption 的关系。我还有一个按钮可以在创建问题时添加选项。每个问题只有一个正确答案。因此,当我创建一个问题并单击Add Option 按钮时,会创建新选项,但与之关联的新radio button 具有不同的name。事实上radio button 的名称是question[options_attributes][i][is_answer] 的形式,其中iid。据我所知radio buttons 应该有same name 作为一个集合或组工作。那么,即使我为一个问题创建了任意数量的选项,我如何才能使其作为一个小组工作呢?

html.erb

<%= form_for @question do |form| %> 

  <div class="field">
    <%= form.label :body %>
    <%= form.text_area :body %>
  </div>

  <%= form.fields_for :options, question.options.each do |a| %>
    <div class="field">
      <%= a.label :options %>
      <%= a.text_area :body %>
      <%= a.radio_button :is_answer, "options" %>
      <%= a.check_box :_destroy %>
      <%= a.label :_destroy, 'delete' %>
    </div>    
  <% end %> 
 <%= form.submit 'Add option', :name => "add_option" %>
 <%= form.submit 'Delete options', :name => "remove_option" %>

  <div class="actions">
    <%= form.submit %>    
  </div>

<% end %>

controller.rb

class QuestionsController < ApplicationController
def new
    @question = Question.new
    @question.options.build
  end
def create
    @question = Question.new(question_params)
    @question.user = current_user
    if params[:add_option]
      @question.options.build
    else
      respond_to do |format|
        if @question.save
          format.html { redirect_to @question, notice: 'Question was successfully created.' and return }
          format.json { render :show, status: :created, location: @question }          
        else
          format.html { render :new }
          format.json { render json: @question.errors, status: :unprocessable_entity }
        end
      end
    end
    render :action => 'new'
  end
private
    # Use callbacks to share common setup or constraints between actions.
    def set_question
      @question = Question.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def question_params
      params.require(:question).permit(:body, options_attributes: [:id, :body, :question_id, :created_at, :updated_at, :is_answer])
    end
end

【问题讨论】:

    标签: html ruby-on-rails radio-button


    【解决方案1】:

    有两种选择:

    1. 在客户端使用 JavaScript 取消选中单选按钮。
    2. 使用同名的单选按钮。在这种情况下,您将不得不更改传递:is_answer 参数的方式并手动分配options_attributes 中的值。

    方法一详解:

    看到这个问题radio different names - only check one

    方法二详情:

    除了为每个选项传递 :is_answer 参数外,您还可以为选择答案 ID 作为值的问题传递单个参数。让我们将其命名为"answer_id"。我们希望这个参数在params[question] 在控制器中散列,所以全名将是"question[answer_id]"。虽然每个选项都会生成单选按钮,但只有选择的按钮会被发送到服务器,因为它们都具有相同的名称。

        <%= form.fields_for :options, question.options.each do |a| %>
          <div class="field">
            <%= a.label :options %>
            <%= a.text_area :body %>
            <%= radio_button_tag "question[answer_id]", a.object.id, a.object.is_answer? %>
            <%= a.check_box :_destroy %>
            <%= a.label :_destroy, 'delete' %>
          </div>    
        <% end %>
    

    https://apidock.com/rails/v4.2.7/ActionView/Helpers/FormTagHelper/radio_button_tag

    在控制器中,您必须根据answer_id 值手动分配选项的is_answer 参数。

    def question_params
      result = params.require(:question).permit(:body, :answer_id, options_attributes: [:id, :body, :question_id])
    
      answer_id = result.delete(:answer_id)
    
      result[:options_attributes].values.each do |option_attrs|
        option_attrs[:is_answer] = option_attrs[:question_id] == answer_id
      end
    
      result
    end
    

    如果您需要更多详细信息,请告诉我。我会更新答案以提供更多信息。

    【讨论】:

    • 添加了更多细节
    • 我尝试了第二种方法。我在这一行 result.options_attributes.each do |option_attrs| 收到 undefined method options_attributes' 的 #result[:options_attributes].each do |option_attrs|。现在我收到此错误:no implicit conversion of Symbol into Integer 在这一行:option_attrs[:is_answer] = option_attrs[:question_id] == answer_id
    • question 对象是这样的:Parameters: {"utf8"=&gt;"✓", "authenticity_token"=&gt;"", "question"=&gt;{"body"=&gt;"Which is the capital of Russia?", "options_attributes"=&gt;{"0"=&gt;{"body"=&gt;"Moscow", "_destroy"=&gt;"0"}, "1"=&gt;{"body"=&gt;"St Petersburg", "_destroy"=&gt;"0"}}, "answer_id"=&gt;"on"}, "commit"=&gt;"Create Question"}
    • result[:options_attributes]改成result[:options_attributes].values
    • 另一个问题:选中的单选按钮没有将is_answer 的值更改为true。我将默认设置为false。所以即使我选择了一个单选按钮,数据库中的值仍然是false
    猜你喜欢
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 2016-11-17
    相关资源
    最近更新 更多