Anything wrong with this plan for my model associations - ruby-on-rails

I'm creating an app that allows users to take multiple choice quizzes that I create.
There's a Quiz model, a Question Model, and an Answer model. The Quiz model has_many questions which has_many answers (and they all belongs_to the model intuitively above them). answers will have a correct_answer boolean attribute that indicates ONE of the answers to be the correct answer. (and they all belongs_to the model intuitively above them). This is to create the quiz.
To provide support for user input once the quiz has already been created, I want to define two other models: SubmittedAnswer and SubmittedQuiz. SubmittedSurvey belongs_to User, and also belongs_to Quiz (both of which has_many submittedsurveys). SubmittedQuiz also has_many submittedanswers.
So when you visit the page that displays the quiz, it allows user input which submits data that sets submittedanswers. Then, since submittedQUiz belongs_to Quiz, I can compare submittedanswers to the answers themselves and grade the quiz. Is this reasonable or should I do it some other way?

I think SubmittedAnswer should have a link (belong_to :answer) so that you can know which answer (and by relation which question) the user responded to.

Related

Rails 5: Many-to-Many relationships and Controllers

Per a previous post , I understand how to set up my tables/Models so that I can setup a Many-to-Many relationship
However, what I am trying to do is to implement all of this on 1 page with 1 form. (The only other page the user will see is a confirmation page after they have submitted the form, possibly just displaying the details of what they submitted)
The User only needs to be able to update the quantities of any of the available Meals. I will then make a backup of the database on a certain day/time and that will be every User's order for the week. Because of this, I have restructured my tables as follows...
User stores the user's information.
user.rb
class User < ApplicationRecord
has_many :mealselections
has_many :meals, through: :mealselections
accepts_nested_attributes_for :mealselections
end
Meal is used to display the information of the meals to all users. (meal_name, description, img_url)
meal.rb
class Meal < ApplicationRecord
has_many :mealselections
has_many :users, through: :mealselections
end
MealSelection is the joined table that references the Meals the User chose, and then an additional integer column is added to this table that denotes the qty of meals they want for each meal selection
mealselection.rb
class MealSelection < ApplicationRecord
belongs_to :user
belongs_to :meals
end
So where I am lost is how to utilize the controller to be able to perform CRUD functionality from a single form. This made more sense when I had a 1-to-1 relationship as I was just updating the columns (meal1, meal2, meal3) for the related user and each meal# column was created with a default value of 0.
However now because of how Many-to-Many relationships work, I realize that the user at minimum has to create and update columns from the same form.
Since I am showing this on one page (homepage), how do I make this happen in the respective HomeController with one form/request?
Though a little dated, the content in http://railscasts.com/episodes/196-nested-model-form-revised demonstrates a common technique which involves modifying the form as the user is making selections to create, remove, or modify the fields of the nested model(s) using javascript. This basic principle is still commonly used, as it leans on the default nested attribute logic in the controller and model mass-update mechanisms. There are some minor tweaks you may have to make with strong parameters being a factor on more modern apps than was common at the time the content was produced. A look at the code for the form and controller action(s) in question might help with a more specific answer as well.

Rails: Marking content as complete for individual users, when content is common across them

I'm relatively new to Rails, so apologies in advance if this is an obvious question. I could not find an answer through searching.
I'm building a basic application which acts as an educational course - users can view lessons, take in the content, and mark lessons as 'complete' accordingly.
I would like users to be able to see which lessons are complete, by marking them as such in the course overview.
I have a Users model and a Lessons model, and the lessons are identical per user at present. If lessons were unique per user, this would presumably be solvable with a boolean 'complete' column for each lesson. This is not the case in this application, however - some users will have completed a lesson; others will not have.
How would I best go about a solution to this? All suggestions and ideas welcome.
Use many-many association and establish relationship among the 3 models.
class Student < ActiveRecord::Base
has_many :progresses
has_many :subjects, through: :progresses
end
class Subject < ActiveRecord::Base
has_many :progresses
has_many :students, through: :progresses
end
class Progress < ActiveRecord::Base
belongs_to :student
belongs_to :subject
end
To be precise use this link to get good understanding on many-many association :)
Third model, say Progress or Completion or Grades or UserLessons... that will belong to user and lesson, and have a field called complete or score or grade....
It's a classic case of many-to-many relation.
User can read multiple lessons
Lessons could be read/complete by multiple users
So to do this is to create another model with column user_id lesson_id as a foreign key for user and lesson and create an additional column completed boolean

How to create voting to a multiple choice application using ruby on rails

I am working on a multiple choice question and answer application using Ruby on Rails and I have the following model.
class User < ActiveRecord::Base
has_many :questions
end
class Question < ActiveRecord::Base
belongs_to :user
has_many :answers
end
class Answer < ActiveRecord::Base
belongs_to :question
has_many :votes
end
class Vote < ActiveRecord::Base
belongs_to :user
belongs_to :answer
end
My problem is a user can choose all the answers.
How can I fix it so that it updates to the new answer?
For example, a has 5 votes and b 3 votes.
User clicks on a and a increments to 6 votes, same user comes back and clicks on b, a decrements back to 5 votes and b increments to 4 votes.
My first guess is that I need to add another model for example, user_choice with user_id and vote_id to track the previous answer.
You have your answer within the models. Just add a point system to the question model.
Under the question model,
def points
self.answers.count
end
Or, if answers have different values attached to them, make points an attribute of the answer instances.
def points
self.answers.pluck(:points).inject(:+)
end
This will sum up all the points from an answer belonging to a question, which allows you to order the questions by point count.
However, I am assuming you will need a Choice model for a question, unless that is in fact what the votes are for.
question has_many choices
choices belong_to question, etc.
I'm not sure what you mean when you say:
How can I fix it so that it updates to the new answer?
EDIT
Er, okay so you just need exactly what I mentioned earlier. A vote is really just the number of times an answer has been chosen.
If your problem is that users can choose more than 1 answer, it is likely that you should implement view based validations via javascript, or better yet, just disable their ability to select multiple choices, which if you were using a select tag, is actually the default. You must've added
multiple: true
in the select tag options for the user to select multiple entries.
On the backend, you can do this:
class Choice < ActiveRecord::Base
validates_uniqueness_of :user_id, scope: [:question_id, :answer_id]
end

Rails User Rating Another User

I am working on an application where a user has the ability to leave feedback on another user. Currently, I already have an implemented user model.
Is this considered a self referential association?
This seems a bit wierd to me (how to set it up through Active Record Associations).
How would I go about setting this association up, what type of association is it? Anything I need to watch out for while going about this (tips, suggestions, errors that may come up)?
According to Answers Below Would This be the Way?
(one to many between users and ratings and one to one between ratings and user)
class User < ActiveRecord::Base
has_many :ratings
end
class Ratings < ActiveRecord::Base
belongs_to :user
end
This may not be in Rails/Active Record terms but ORM generic.
I would probably implement this by having a Feedback or Review model and your User model would have one-to-many Feedback/Reviews and the Feedback/Review would have a one-to-one relationship with the User who created it.
EDIT: Response to question update...
You can have an User object on the Ratings model that is the author. My rails experience is minimal but I believe your Ratings model would look like this.
class Ratings < ActiveRecord::Base
belongs_to :user
has_one :user
end

HABTM, or multiple belongs_to?

I'm teaching myself Rails, and as a test project I'm mocking up a simple question/answer app similar to stackoverflow.
In my simplified version I have:
questions
answers
users (the authors of questions and answers)
I get that answers belong to questions.
What's the proper relationship between users and questions?
What's the proper relationship between users and answers?
It would seem to me that questions and answers don't really "belong_to" users, and instead questions and answers "has_one user" (the author). But that doesn't seem right either, because then the user would "belong_to question" and "belong_to answer".
Is HABTM the answer between the three classes?
Lots of people get stuck on this relationship thing, don't they? :)
Is HABTM the answer between the three classes?
No. You don't need HABTM in any of these relationships.
What's the proper relationship between users and questions?
What's the proper relationship between users and answers?
In both of these cases, it is a one-to-many relationship: A user has many questions and a user has many answers.
From a logical point of view, consider this: One question can never be authored by multiple users and one answer cannot be authored by multiple users. As such, it's not a many-to-many relationship.
In this case, your classes should be set up like this:
class User < ActiveRecord::Base
has_many :questions
has_many :answers
end
class Question < ActiveRecord::Base
belongs_to :user
has_many :answers
end
class Answer < ActiveRecord::Base
belongs_to :user
belongs_to :question
end
If you, on the other hand, have a tagging system similar to StackOverflow, you'll need a HABTM relationship. One question can have many tags, while one tag can have many questions. As a prime example, your post has three tags (ruby-on-rails, habtm, foreign-key-relationship), while the ruby-on-rails tag presently have 8,546 questions.
Belongs_to is a strange name. Figure out your has_many relationships and just put belongs_to on the other side and don't worry about the semantics of it.

Resources