Manage multiple association of two classes in rails - ruby-on-rails

I want to manage the association of one to many type, for user and answers and association of many to many type, for vote management for the same two models i.e users and answers.
So, how to maintain both the associations at the same time?
This code is something that I want to implement.
class User < ActiveRecord::Base
has_many :answers #For the answers of particular user
has_and_belongs_to_many :answers #For the answers upvoted by a particular user
end
class Answer < ActiveRecord::Base
belongs_to :user #Author of the answer
has_and_belongs_to_many :users #For those who upvoted the answer
end

You should give a different name to the other association, but then you would also need to specify class name.
has_many :answers
has_and_belongs_to_many :voted_answers, class_name: "Answer"

Related

Ruby on Rails has_many :through in a polymorphic association

I have searched and searched and found only partial solutions to my current question.
The thing is, I'd like to know if it is possible to use has_many :through along with a polymorphic association in Ruby on Rails.
I have a system where students can create travel plans (that can belong to many students) and refund claims (that can belong to only one student) for their projects. In this system, both admin users and students are able to comment on the plans and claims.
My associations are:
class Student < ActiveRecord::Base
has_and_belongs_to_many :travel_plans
has_many :refund_claims
has_many :comments, through: :travel_plans
has_many :comments, through: :refund_claims
end
class AdminUser < ActiveRecord::Base
has_many :comments
end
class TravelPlan < ActiveRecord::Base
has_and_belongs_to_many :students
has_many :comments, as: :commentable
end
class RefundClaim < ActiveRecord::Base
belongs_to :student
has_many :comments, as: :commentable
end
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
My questions are:
Is it correct to associate comments twice in the Student model?
I don't want the AdminUsers to have travel plans and refund claims, how can I identify their comments as being made on a travel plan or on a refund claim?
Would there be a better approach?
Thanks a lot in advance for everyone!
Cheers,
You probably want to add an polymorphic author attribute to the Comment model. Than you just need has_many :comments, as: :author to the Student and AdminUser model.
If this is a new application and you are starting on the green field you might want to rethink your models a bit and add a Role and a User model. Student would than be a role of user as would AdminUser be.
Is it correct to associate comments twice in the Student model?
No, not really. If you have duplicate association name, you can only use one of them. If you want to use both, you have to name them differently.

How to store related model data on through model in Rails

I am using a :through relationship between 2 models because I have extra data I want to store in the join table -- otherwise I would just use the :source relationship.
But the data I want to store is dynamic -- it's a list of questions that have been added to an instance of one of the models I am joining. Example:
Physicians add unique questions that patients should answer when making an appointment -- Dr. Foo wants his patients to answer 'height' and 'weight', while Dr. Bar wants his patents to answer 'age' and 'gender'.
What is the cleanest way to store the answers to these questions in the Appointment model instance?
current Models:
class Question < ActiveRecord::Base
belongs_to :physician
end
class Physician < ActiveRecord::Base
has_many :questions
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, through: :appointments
end
Thanks in advance -- I have come across this several times and would love to hear a good answer on it -- another example is: User takes a Quiz. Quiz has_many Questions.
How would you store the unique answers to the static set of questions each Quiz has? Again, I'm stuck at using a :through relationship using a join table called Attempts.
Possible solution I thought of: Patient has_many Surveys and Survey has_many Answers. Create this when a new Appointment is made. Problem is, I'm finding the views and controllers to be quite complex for something as simple as, to restate my question, store data related to a joining table.
I'd recomend adding a new model called Answer for storing this information. Something like
class Answer < ActiveRecord::Base
belongs_to: appointment
belongs_to: patient
end
The relationship with the Question model could be difficult to maintain. Think of a question that has already been ananswered and changes its text from 'how old are you?' to 'when did you born?'. You'll have to prevent this change at the question model or store the question text with the answer and forgot the relationship.
Another option would be to use a serialized atribute on the appointment model to store its questions and answers.
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
serialize :answers
end
You'll need to add a text attribute to the appointment table called answers
The answers attribute will be a hash where you can save something like {question_text_1: answer_1, question_text_2: answer_2}. This will allow you to easily use it on the view.
It's also easy to write the method to save/update this attribute allowing an easy form on the corresponding view.
Again, it's necesary to define what will happen to old appointments when a physician changes question titles.
I think you need two extra tables here: Answer, and AppointmentQuestion. There is the tricky issue of the questions_to_ask, the questions_answered and answers. I've addressed the questions_to_ask by delegating from the appointment to the physician, giving Appointment.physician_questions. The idea is the appointment will know what questions to ask, and will store the questions answered
I got to this solution by drawing entiry relationship diagrams and then looking at creating intermediate object where m-m relationships exist. The stuff below isn't complete.
This suggests a general solution of having a table that contains a row for each time the question is asked (perhaps rename AppointmentQuestion to AskedQuestion)
AppointmentQuestion
belongs_to :question
belongs_to :appointemnt
has_one :answer
Answer
belongs_to :AppointmentQuestion
Appointment
belongs_to :physician
belongs_to :patient
has_many questions through appointment_question
has_many answers through appointment_question
delegate :questions, to: :doctor, prefix: true
Patient
has_many appointments
Physician
has_many appointments
has_many questions
Question
belongs_to physician
has_may answers through appointment_question
I don't know which database you are using but to me that looks like the perfect example for using Postgres HStore. Considering your data is dynamic, unstructured.
http://www.postgresql.org/docs/9.1/static/hstore.html
You could have a field questions of the type hstore
On your appointment migration
def change
create_table :named_searches do |t|
t.hstore questions
end
end
And you would have that field available on your models (it works like a hash with key value pairs, questions and answers in your case)
When you query for questions on that case, you will get a list of questions with their respective answers, and although the list is dynamic (any question can be added/the appointments don't need to have the same questions), it can be saved to the database seamlessly

Tracking user stats in my data model

I'm getting crazy adding some features to my quiz app based on Rails and Active Record.
This is my actual data model:
class Quiz < ActiveRecord::Base
has_many :quiz_questions
has_many :questions, through: :quiz_questions
belongs_to :user
end
class Question < ActiveRecord::Base
belongs_to :section
has_many :answers
has_many :quiz_questions
has_many :quizzes, through: :quiz_questions
end
class Answer < ActiveRecord::Base
belongs_to :question
end
class Section < ActiveRecord::Base
has_many :questions
end
class User < ActiveRecord::Base
has_many :quizzes
end
Question and answer are obvious: I store the questions and every question has some answer.
The logic now is working right.
User create a quiz, the system take some random questions and add them to the join table.
I must add now some stats: I want to add the possibility for every user to track the right answer percentage and the questions with more errors and I want also to give to every user the possibility to choose a "quiz generation strategy", overriding the "randomness" of the question choice. User for example can create a quiz with questions he never answered (there are about 1200 question in the table and every quiz has 30 questions), or user can create a quiz with questions he wrongs often.
I cannot find a way to add these counters in a smart way. I have my join table, but using the join table I have poor performance. Any idea?

Modeling a Poll Feature

I'm developing a poll feature that allows users to create poll questions with options and allow other users to answer them
The answer model includes an option_id column but the two models are not related.
I have two questions:
Do my models (below) fully encapsulate what I'm trying to represent?
How would the create method for an answer controller action look? (Specifically, how to retrieve the option_id)
Note: I've never dealt with this pattern in which a model(answer) references another model (option) via option_id but the two aren't related
So far I have this:
class Question < ActiveRecord::Base
belongs_to :user
has_many :options
has_many :answers
end
class Option < ActiveRecord::Base
belongs_to :question
end
class Answer < ActiveRecord::Base
belongs_to :user
belongs_to :question
end
Found a tut for a mobile app doing this

Can a single model "belong_to" more than one parent model?

Just as on StackOverflow, in my app a User can write Questions and can also provide Answers:
class User < ActiveRecord::Base
has_many :questions
has_many :answers
end
class Question < ActiveRecord::Base
has_many :answers
belongs_to :user
end
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
My question has to do with the Answer model above:
Is it ok for an Answer to belong_to both the User and the Question models?
I have a feeling I read somewhere that a model can only have a single foreign key. If so, how do I rectify that?
Yes, it is perfectly ok and you will have many models that have many belongs_to as your domain model gets more complex. I don't know where you would have read that a model can only have a single foreign key.

Resources