Вопрос

I have a Survey which can participated by Participants:

Survey has_many: Questions which has_many: Answers

A Participant should be able to add his Voting to each of the Answers (values are [-1,0,1] )

One question looks like this:

Question 1
 - Answer1 -> Please vote -1 / 0 / 1 (Checkbox field)
 - Answer2 -> Please vote -1 / 0 / 1 (Checkbox field)
 - Answer3 -> Please vote -1 / 0 / 1 (Checkbox field)
 - Participant Comment               (Text Field)
 - Participant Average               (Rating Field)

How do I save a voting correctly? I wanna keep the participant_id, answer_id AND voting_value get saved.

ADDED for explanation:

(User will get answer)

User < ActiveRecord::Base
  has_and_belongs_to_many :surveys
  has_many :participants
end

Survey < ActiveRecord::Base
  belongs_to :user
  has_many :questions
end

Question < ActiveRecord::Base
  belongs_to :survey
  has_many :answers
end

Answers < ActiveRecord::Base
  belongs_to :question
  has_many :votings
end

Voting < ActiveRecord::Base
  belongs_to :answer
  belongs_to :participant
  attr_accessible :value
end

Participant < ActiveRecord::Base
  has_many :votings
  belongs_to :user
end
Это было полезно?

Решение

I think your participant and user models need to be merged into one because isn't participant an user? I do not see why Participant model would be necessary here.

Say, we merge User and Participant into just User, the association between User and Voting would then be:

User < ActiveRecord::Base
  has_and_belongs_to_many :surveys
  has_many :votings 
end

Voting < ActiveRecord::Base
  belongs_to :answer
  belongs_to :user
  attr_accessible :value
end

Now from your first code block:

Question 1
 - Answer1 -> Please vote -1 / 0 / 1 (Checkbox field)
 - Answer2 -> Please vote -1 / 0 / 1 (Checkbox field)
 - Answer3 -> Please vote -1 / 0 / 1 (Checkbox field)
 - Participant Comment               (Text Field)
 - Participant Average               (Rating Field)

Isn't voting done on answers by users? In that case do we need user has_many :votings relationship? I think the association spoken out would be User takes many Surveys, Survey has many Questions, Question has many Answers and Answer has many Votings. Each of which votings may be checked. So for this I don't think a direct association between User and Voting is the solution.

Following is updated User, Answer and Voting models with updates association:

User < ActiveRecord::Base
  has_and_belongs_to_many :surveys
end

Answer < ActiveRecord::Base
  belongs_to :question
  has_many :votings
end

Voting < ActiveRecord::Base
  belongs_to :answer
  attr_accessible :value
end

Finally there a couple of other minor typos like Answers < ActiveRecord::Base where class Answer should not be plural.

The second problem is you have User has_and_belongs_to_many Surveys. You are defining many to many relationship between User and Survey so you need to define the same in your Survey model as well:

Survey < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_many :questions
end

With all those updates your models along with relationships would look as follows (Note: I've also added accepts_nested_attributes_for in models so that when your form submits you don't need to manually build each of the associated objects):

User < ActiveRecord::Base
  has_and_belongs_to_many :surveys
end

Survey < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_many :questions

  accepts_nested_attributes_for :questions
end

Question < ActiveRecord::Base
  belongs_to :survey
  has_many :answers

  accepts_nested_attributes_for :answers
end

Answers < ActiveRecord::Base
  belongs_to :question
  has_many :votings

  accepts_nested_attributes_for :votings
end

Voting < ActiveRecord::Base
  belongs_to :answer
  attr_accessible :value     
end

With the above model relationshp you could build your SurveysController's new and create action would look similar to follows:

# app/controllers/surveys_controller.rb
class SurveysController < ApplicationController

  def new
    @survey = current_user.surveys.build do
    @question = @survey.questions.build
    @answer = @question.answers.build

    # Build three different votings for answer with default value.
    [-1, 0, 1].each do |voting_value| 
      @answer.votings.build(value: voting_value)
    end
  end


  def create
    @survey = current_user.surveys.build(params[:survey])
    @survey.save 
    # Of course you would check if save succeeded or failed and take action accordingly.
  end
end

Also, I'd recommended you to look into has_many...through instead of has_and_belongs_to_many for defining many to many relationship.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top