1

I want a User to be able to answer all questions that are assigned to them, in an Answer model. Now I'm trying to create a form that allows me to loop through the questions a User have assigned to them, and answer them in an Answer model.

In the answer model I save the reply, and the question id. However this requires multiple saves in one form, which I'm unable to do.

Model associations look like this:

User

has_many :answers
has_many :questions, through: :question_participants

Answer

belongs_to :user
belongs_to :question

now I'm trying to create an Answer#new form like this:

  <%= form_for @answer do |f| %>
    <% @questions.each do |question| %>
        <h3><%= question.name %></h3>
        <%= f.hidden_field :question_id, value: question.id %>

          <%= f.text_field :reply, class: 'form-control' %>

    <% end %>

    <%= f.submit 'Send inn', class: 'btn btn-success' %>
  <% end %>

and thus hoping it will allow me to save multiple columns in one, but that doesn't work. It only saves the last column, no matter what.

My answers controller:

class AnswersController < ApplicationController

  def new
    @questions = current_user.questions
    @answer = current_user.answers.new
  end

  def create
    @questions = current_user.questions
    @answer = current_user.answers.new(answer_params)
    if @answer.save
      redirect_to answers_path
    else
      render 'new'
    end
  end

  private

  def answer_params
    params.require(:answer).permit(:reply, :question_id)
  end
end

1 Answers1

0

What you're looking for is accepts_nested_attributes_for:

This should work:

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :answers
   has_many :questions, through: :answers
   accepts_nested_attributes_for :answers

   #this will have to be populated on user create
   before_create :build_answers

   private

   def build_answers
       questions = Question.find [1,3,4,6]
       questions.each do |question|
          user.build_answer(question: question)
       end
   end
end

#app/models/answer.rb
class Answer < ActiveRecord::Base
   #columns id | user_id | question_id | response | created_at | updated_at
   belongs_to :user
   belongs_to :question
end

#app/models/question.rb
class Question < ActiveRecord::Base
   has_many :answers
   has_many :users, through: :answers
end

This will give you the ability to do the following:

#config/routes.rb
resources :answers, only: [:edit, :update]

#app/controllers/answers_controller.rb
class AnswersController < ApplicationController 
   def edit
      @questions = current_user.questions
   end

   def update
      @answers = current_user.answers.update answer_params
   end

   private

   def answer_params 
      params.require(:answer).permit(:response) #-> question_id and user_id set on create, don't need to be changed
   end
end

This will allow you to use the following form:

#app/views/answers/edit.html.erb
<%= form_tag answers_update_path, method: :patch do |f| %>
   <% @questions.each do |question| %>
      <%= f.fields_for "answers[]", question do |qf| %>
         <%= qf.label question.title %>
         <%= qf.text_field :response %>
      <% end %> 
   <% end %>
   <%= f.submit %>
<% end %>

--

Typically, you'd use the accepts_nested_attributes_for with the nested model. However, since you just want multiple answer responses, you can use the above.

The bugs in this would likely be in the strong params, or in the form declaration (IE current_user.questions). If you reply with information, I'll write some upates


Ref: Multiple objects in a Rails form

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • Hey Rich, I've tried following what you suggested, but how can you access the answers edit, when there is no :id? Also you want to run build answers on the creation of the user, but what happens then if a question is added at a later stage. The way my system work is that you register your user, and are a part of a company, then you'll have an admin ask you questions and assign questions to you. – Sebastian Jennings Almnes Oct 13 '15 at 09:58