Modeling a Poll Feature - ruby-on-rails

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

Related

How to set up associations for accepting one proposal in Rails?

I am developing a feature in a Rails app that allows users to create projects. Then, other users can create proposals. Finally, the user that created the project can accept one of the proposals as the accepted proposal.
What is the best way to allow the user that created the project (the manager) to select one of the proposals as the accepted proposal?
The models are set up like this:
User model
class User < ApplicationRecord
has_many :projects
has_many :proposals
end
Project model
class Project < ApplicationRecord
belongs_to :manager, class_name: 'User', foreign_key: :user_id
has_many :proposals
end
Proposal model
class Proposal < ApplicationRecord
belongs_to :project
belongs_to :user
end
At first, I thought about an "accepted" boolean in the proposal table that would allow the user to mark the boolean as true to make the proposal "accepted". But this could lead to problems like some projects having more than one accepted proposal. It isn't the correct way to do this.
So, how should I set up an acceptance model that allows the manager to select and de-select a proposal as the one and only "accepted" proposal?
If you want to be 100% sure that no project can have more than one accepted proposal, then you can set it up with an additional relation. You would also need another relation inside Proposal
class Project < ApplicationRecord
belongs_to :accepted_proposal, class_name: 'Proposal', inverse_of: :accepted_for, optional: true
end
class Proposal < ApplicationRecord
has_one :accepted_for, class_name: 'Project', inverse_of: :accepted_proposal
end
You can also validate uniqueness only for accepted proposals, but I think you can't have a database unique index for this
class Proposal < ApplicationRecord
validates :project_id, :uniqueness, if: Proc.new { |proposal| proposal.accepted }
end

Using a junction table with its own relationship

I'm creating an app that has a User and a Plugin model. A user can have multiple plugins and a plugin can belong to multiple users, which I've implemented using a junction table.
class Plugin < ActiveRecord::Base
has_many :user_plugins
has_many :users, through: :user_plugins
end
class User < ActiveRecord::Base
has_many :user_plugins
has_many :plugins, through: :user_plugins
end
class UserPlugins < ActiveRecord::Base
belongs_to :user
belongs_to :plugin
end
However, I then want to store arbitrary data for each user plugin (for example, things like api keys, options etc that can differ for each plugin.).
My initial approach was to have a user_plugins_options that joined on user_plugins, but I can't seem to get this to work correctly.
class UserPluginOptions < ActiveRecord::Base
belongs_to :user_plugins
end
My question, how should I go about approaching this to best work with ActiveRecord?
I think you misnamed your class, as the table is user_plugins but the model is UserPlugin. It’s plausible you are running into issues because of this.
Agree with Alex. Why don’t you create a json field on UserPlugin called options and keep a hash of plugin specific values here.
If you must have another table, you should add a has_one :user_plugin_option to your UserPlugin

Designing Database for Long Forms in Rails & ActiveRecord

I want to store complex form/questionnaire data but I'm having a hard time designing the database:
A User can create a new Exam. When creating an Exam, the user needs to choose from a template with 30 pre-set questions (and I want to store the answer to each of these questions in the database).
Purpose of the template is so that practitioners might want to run different exams (e.g. knee exam, arm exam, spine exam etc). So they create a new exam, choose a specific template. And each template has many questions
What's the best way to design this database? I started creating Exam, Template, and Question models, but then I got lost building the relationships.
Here's how I ended up designing the database. I added a 4th "answers" model. This way, I can associate answers to questions, and questions to templates, and templates to exams.
Hope this helps someone
class User < ActiveRecord::Base
has_many :patients
has_many :assessments
end
class Patient < ActiveRecord::Base
belongs_to :user
has_many :assessments
end
class Assessment < ActiveRecord::Base
belongs_to :user
belongs_to :template
belongs_to :patient
has_many :questions, :through=> :template
has_many :answers, :through=> :questions
end
class Template < ActiveRecord::Base
belongs_to :user
has_many :questions
end
class Question < ActiveRecord::Base
belongs_to :template
has_one :answer
end
class Answer < ActiveRecord::Base
belongs_to :question
end

multiple models in Rails with a shared interface

I'm not sure of the best structure for a particular situation in Rails. We have several types of workshops. The administration of the workshops is the same regardless of workshop type, so the data for the workshops is in a single model. We collect feedback from participants about the workshops, and the questionnaire is different for each type of workshop. I want to access the feedback about the workshop from the workshop model, but the class of the associated model will depend on the type of workshop. If I was doing this in something other than Rails, I would set up an abstract class for WorkshopFeedback, and then have subclasses for each type of workshop: WorkshopFeedbackOne, WorkshopFeedbackTwo, WorkshopFeedbackThree. I'm unsure how to best handle this with Rails.
I currently have:
class Workshop < ActiveRecord::Base
has_many :workshop_feedbacks
end
class Feedback < ActiveRecord::Base
belongs_to :workshop
has_many :feedback_ones
has_many :feedback_twos
has_many :feedback_threes
end
class FeedbackOne < ActiveRecord::Base
belongs_to :feedback
end
class FeedbackTwo < ActiveRecord::Base
belongs_to :feedback
end
class FeedbackThree < ActiveRecord::Base
belongs_to :feedback
end
This doesn't seem like to the cleanest way to access the feedback from the workshop model, as accessing the correct feedback will require logic investigating the Workshop type and then choosing, for instance, #workshop.feedback.feedback_one.
Is there a better way to handle this situation? Would it be better to use a polymorphic association for feedback? Or maybe using a Module or Mixin for the shared Feedback interface?
Note: I am avoiding using Single Table Inheritance here because the FeedbackOne, FeedbackTwo, FeedbackThree models do not share much common data, so I would end up with a large sparsely populated table with STI.
I think the best solution is create an abstract class Workshop, and 3 subclasses Workshop1, Workshop2 and Workshop3.
Hence, each will have its set of feedbacks, Feedback1 to Workshop1, Feedback2 to Workshop2, ...
You can change the declaration in the subclasses as follows:
class Workshop1 < Workshop
has_many :feedbacks, :class_name => "Feedback1"
end
class Feedback1 < ActiveRecord::Base
belongs_to :workshop, :class_name => "Workshop1"
end
And in your application can use workshop.feedbacks and and feedback.workshop no matter what class the instance of the Workshop or Feedback belongs.
EDIT: You have three types of workshop with information in common, but each workshop has a specific kind of feedback. So it's bestter to use STI for Workshop, and not for Feedback.
You can subclass your models, like so:
class Workshop < ActiveRecord::Base
has_many :feedback_ones
has_many :feedback_twos
has_many :feedback_threes
#has_many :feedbacks # This MIGHT work, but is untested. I'm not at a dev setup to try.
end
class Feedback < ActiveRecord::Base
belongs_to :workshop
has_many :feedback_ones
has_many :feedback_twos
has_many :feedback_threes
end
class FeedbackOne < Feedback
belongs_to :feedback
end
class FeedbackTwo < Feedback
belongs_to :feedback
end
class FeedbackThree < Feedback
belongs_to :feedback
end
This is likely a better solution, and is cleaner. Your Feedback table needs to have a type column, which it uses to use one table for multiple classes. This blog post gives a good basic introduction to the concept of Single Table Inheritance.

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