在Rails应用中选择多个单选按钮

时间:2019-05-06 08:29:51

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

我有一个应用,其中Questionhas_many建立了Option关系。我还有一个按钮可以在创建问题时添加选项。每个问题只有一个正确答案。因此,当我创建一个问题并单击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

1 个答案:

答案 0 :(得分:1)

有两种选择:

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

方法1详细信息:

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

方法2详细信息:

代替为每个选项传递: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

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

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

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