João Belo
João Belo

Reputation: 47

Ruby on rails - adding multiple choice checkboxes - ERROR - undefined method `check_box_tag'

I'm tying do add a new kind of answers to my polls app. It will be a multiple choice with checkboxes. The user can choose one or more possible answers from the checkboxes presented. I'm struggling to make it work, I'm getting the error:

NoMethodError in Replies#new

undefined method `check_box_tag' for #<ActionView::Helpers::FormBuilder:0x007fae8bd82f48>

right i have this models:

answer.rb

class Answer < ActiveRecord::Base
  belongs_to :reply
  belongs_to :question
  belongs_to :possible_answer
end

poll.rb

class Poll < ActiveRecord::Base
  validates_presence_of :title

  has_many :questions
  has_many :replies
end

possible_answer.rb

class PossibleAnswer < ActiveRecord::Base
  belongs_to :question
end

question.rb

class Question < ActiveRecord::Base
  belongs_to :poll

  has_many :possible_answers
  has_many :answers

  accepts_nested_attributes_for :possible_answers, reject_if: proc { |attributes| attributes['title'].blank? }
end

reply.rb

class Reply < ActiveRecord::Base
  belongs_to :poll
  has_many :answers

  accepts_nested_attributes_for :answers
end

In the views I have a reply/new.html.erb that already work for radio and open answer questions, by rendering the partial by kind:

<h1><%= @poll.title %></h1>

<%= form_for [ @poll, @reply ] do |f| %>
    <%= f.fields_for :answers do |c| %>
        <%= render c.object.question.kind, c: c %>
    <% end %>
    <p>
      <%=f.submit 'Finish poll', class: 'btn btn-primary'%>
    </p>
<% end %>

and the partial for the checkbox:

<p>                                                                             
  <%= c.label :value, c.object.question.title %>                                
</p>                                                                            
<div class="checkbox">                                                          
  <% c.object.question.possible_answers.each do |possible_answer| %>            
      <p>                                                                       
        <label>                                                                 
          <%= c.check_box_tag :possible_answer_id, possible_answer.id %>        
          <%= possible_answer.title %>                                          
          <%= c.hidden_field :question_id %>                                    
        </label>                                                                
      </p>                                                                      
  <% end %>                                                                     
</div>

replies_controller.rb

class RepliesController < ApplicationController
  def new
    @poll = Poll.find params[:poll_id]
    @reply = @poll.replies.build
    @poll.questions.each { |question| @reply.answers.build question: question }
  end

  def create
    @poll = Poll.find params[:poll_id]
    @reply = @poll.replies.build reply_params

    if @reply.save
      redirect_to @poll, notice: 'Thank you for the taking the poll.'
    else
      render :new
    end
  end

  private
    def reply_params
      params.require(:reply).permit(:poll_id, {
          answers_attributes: [:value, :question_id, :reply_id, :possible_answer_id] })
    end
end

questions_controller

class QuestionsController < ApplicationController
  before_action :set_question, only: [:show, :edit, :update, :destroy]
  before_action :set_poll
  before_action :set_kind_questions


  def index
    @questions = Question.all
  end

  def show
  end

  def new
    #@question = Question.new
    @question = @poll.questions.build
    5.times { @question.possible_answers.build }
  end

  def edit
  end

  def create
    #@question = Question.new(question_params)
    @question = @poll.questions.build(question_params)

    respond_to do |format|
      if @question.save
        format.html { redirect_to @poll, notice: 'Question was successfully created.' }
        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

  def update
    respond_to do |format|
      if @question.update(question_params)
        format.html { redirect_to @question, notice: 'Question was successfully updated.' }
        format.json { render :show, status: :ok, location: @question }
      else
        format.html { render :edit }
        format.json { render json: @question.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @question.destroy
    respond_to do |format|
      format.html { redirect_to @question, notice: 'Question was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    def set_question
      @question = Question.find(params[:id])
    end

    def question_params
      params.require(:question).permit(:title, :kind, :poll_id, { possible_answers_attributes: [:title, :question_id] })
    end

    def set_kind_questions
      @kind_options = [
          ['Open Answer','open'],
          ['Multiple Radio Choice', 'radio'],
          ['Multiple Checkbox Choice','checkbox']
      ]
    end

    def set_poll
      @poll = Poll.find params[:poll_id]
    end
end

Answers migration table

class CreateAnswers < ActiveRecord::Migration
  def change
    create_table :answers do |t|
      t.references :reply, index: true, foreign_key: true
      t.references :question, index: true, foreign_key: true
      t.references :possible_answer, index: true, foreign_key: true
      t.string :value

      t.timestamps null: false
    end
  end
end

Probably I have to use has_and_belongs_to_many association in the answers model but I'm not getting how. Can someone help me?

Thanks!

Upvotes: 0

Views: 1460

Answers (1)

Yang
Yang

Reputation: 1923

Please try to just use check_box_tag as below:

<%= check_box_tag( 'possible_answer_ids['+ possible_answer.id.to_s+']', possible_answer.id) %>

Upvotes: 1

Related Questions