In my rails app a user can create courses and schools (group). Each time a user creates a course or school their user_id is stored in the database table for the course or school, so a user has_many :schools and :courses and the school or course belongs_to :user. Also, the user can can attend courses and join schools (as student or professor) with a has_many through relationship model (schoolgroups for schools which has a :user_id, school_id, and :role [string], and for courses student_users (and professor_users) which has a :user_id, course_id, and :role [string]. My question is, in the user model can I just specify once that:
has_many :schools, :dependent => :destroy
has_many :courses, :dependent => :destroy
has_many :schoolgroups, :dependent => :destroy
has_many :student_users, :dependent => :destroy
has_many :professor_users, :dependent => :destroy
or would I have to have a user model that looked like this:
has_many :schools, :dependent => :destroy
has_many :courses, :dependent => :destroy
has_many :schoolgroups, :dependent => :destroy
has_many :schools, :through => :schoolgroups
has_many :student_users, :dependent => :destroy
has_many :courses, :through => :student_users
has_many :professor_users, :dependent => :destroy
has_many :courses, :through => :professor_users
You'll need to think about the ownership of the models in a bit more detail. has_many means a many-to-one relationship, so saying Professor has_many Courses means that the professor owns the courses and the course only has one professor (or does it?). So you'll do something like this:
has_many :school, :dependent => :destroy
has_many :courses, :dependent => :destroy
has_many :schoolgroups, :dependent => :destroy
On the other hand, you'll have things that the user is associated to, but other users may also be associated in the same way. For example, a user can be a student in a course, but so can many other students. For this you'll want to use has_and_belongs_to_many or HABTM which represents a many-to-many relationship:
has_and_belongs_to_many :courses_as_student, :class_name => "Course",
:join_table => "student_users"
Then in the Course class:
belongs_to :user
# or even better:
# belongs_to :professor, :class_name => "User", :foreign_key => "professor_id"
has_and_belongs_to_many :students, :class_name => "User",
:join_table => "student_users"
You can read all the details in the Rails documentation.
Related
I'm having a problems with :group and :uniq tags as an option to has_many through collection definition. I have many triple model associations defined on my system and I want to list elements grouped to avoid (the actual) repetition. My main model looks like that:
class Trip < ActiveRecord::Base
belongs_to :agent
has_many :trips_destinations, :class_name => "TripsDestination"
has_many :destinations, :through => :trips_destinations
has_and_belongs_to_many :vibes, join_table: :trips_vibes
has_and_belongs_to_many :verbs, join_table: :trips_verbs
has_many :trips_destinations_activities, :class_name => "TripsDestinationsActivity"
has_many :activities, :through => :trips_destinations_activities, :uniq => true
has_many :trips_destinations_hotels, :class_name => "TripsDestinationsHotel"
has_many :hotels, :through => :trips_destinations_hotels
has_many :trips_destinations_recommended_places, :class_name => "TripsDestinationsRecommendedPlace"
has_many :recommended_places, :through => :trips_destinations_recommended_places
has_many :trips_destinations_transportations, :class_name => "TripsDestinationsTransportation"
has_many :transportations, :through => :trips_destinations_transportations
...
...
end
Anyone know how to list they why avoiding repetition given the pair [trip_id, destination_id]?
And why they are repeated?
My rails version is 4 and I the image below shows the error message when passing grouping options to has_many relation.
Please help!
Your syntax for uniq is not correct for Rails 4.
has_many :activities, -> { uniq }, :through => :trips_destinations_activities
Unique now has scope syntax.
I have 3 tables:
User class
User has_many :project_assignments
User has_many :projects, through: :project_assignments
ProjectAssignment class
ProjectAssignment belongs_to :user
ProjectAssignment belongs_to :project_owner, class_name: 'User', foreign_key: 'user_creator_id'
ProjectAssignment belongs_to :project
Project
has_many :project_assignments
has_many :users, through: :project_assignments
ProjectAssignment has the columns:
project_id, user_id, creator_user_id
I want to get all the projects, for a user through creator_user_id
ex: current_user.created_projects
The query: ProjectAssignment.where(creator_user_id: current_user.id)
Can it be done when defining the relations in the models, the same as I did with projects but the foreign_key should be creator_user_id
I think you just need another couple of associations in User which leverage the creator_user_id field (as opposed to user.projects which will return the projects the user is a member of)
Try this -
#in User class
has_many :owned_project_assignments, :class_name => "ProjectAssignment", :as => :project_owner, :foreign_key => "user_creator_id"
has_many :owned_projects, :through => owned_project_assignments, :class_name => "Project", :source => :project, :as => :project_owner
the :source and :as options can be a bit tricksy, so this might not work, it's just off the top of my head...
In my case this was the correct solution:
has_many :owned_project_assignments, class_name: "ProjectAssignment", foreign_key: 'user_creator_id'
has_many :owned_projects, through: :owned_project_assignments, source: :project
assignment (id, name, date)
activity (id, name, desc)
student (id, name, email)
An assignment can have many activities, an assignment can assign to many students.
Need to track status of each activity for a student.
So have a three primary keys table:
assignments_activities_students (assignment_id, activity_id, student_id, status)
Set the association below, but it doesn't work. Anyone know how to do this?
assignment
has_many :assignments_activities_students
has_many :students, :through => :assignments_activities_students
has_many :activities, :through => :assignments_activities_students
activity
has_many :assignments_activities_students
has_many :assignments, :through => :assignments_activities_students
has_many :students, :through => :assignments_activities_students
student
has_many :assignments_activities_students
has_many :assignments, :through => :assignments_activities_students
has_many :activities, :through => :assignments_activities_students
assignments_activities_students
belongs_to :assignment
belongs_to :activity
belongs_to :student
You have a Student model, but you're adding relationships with
has_many :users, :through => :assignments_activities_students
You should change this to the following in your Assignment and Activity models.
has_many :students, :through => :assignments_activites_students
I need to write a scope that I will pass a user's id through and will collect all the user's list associates with all the companies for that user from the users table.
In User.rb:
has_many :employments
has_many :companies, :through => :employments, :dependent => :destroy
...
In Employment.rb:
belongs_to :user
belongs_to :company
In Company.rb:
has_many :employments
has_many :users, :through => :employments, :dependent => :destroy
This could be possible using something like:
current_user.companies.each{|c| c.users.each {|u| u}}
but writing like this I think is much more time consuming.
The following (not tested) scope finds all companies where a given user had work.
class Company
has_many :employments
has_many :users, :through => :employments, :dependent => :destroy
scope :with_user, lambda { |user_id| joins(:employments).where(:user => user_id) }
...
Run rails c and execute try Company.with_user(User.last!.id) and see what happens.
Below are the models that are relevant to my problem. I am attempting to design a way to display CourseEnrollments along with their steps to a given patient. Here is what I have come up with so far.
INDEX ACTION - /course_enrollments/ --> Display courses user is enrolled in as well as the most recent course overview. This can redirect to most recent course.
SHOW ACTION - /course_enrollments/:id --> Display courses user is enrolled in as well as the most recent course overview
The part I am struggling to figure out is how to display an individual step for a course. Should this be done in the course_steps controller (which is nested inside the courses resource)?
class Course < ActiveRecord::Base
belongs_to :course_category
belongs_to :client
belongs_to :user_created, :foreign_key => :user_created_by, :class_name => "User"
belongs_to :user_updated, :foreign_key => :user_last_updated_by, :class_name => "User"
has_many :course_steps, :dependent => :destroy
has_many :steps, :through => :course_steps
has_many :course_requests, :dependent => :destroy
has_many :course_enrollments, :dependent => :destroy
has_many :patients, :through =>:course_enrollments
end
class CourseStep < ActiveRecord::Base
belongs_to :step
belongs_to :course
validates_uniqueness_of :step_id, :scope => :course_id
end
class Step < ActiveRecord::Base
belongs_to :step_type
belongs_to :client
has_one :step_quiz, :dependent => :destroy
has_one :step_survey, :dependent => :destroy
has_one :step_text, :dependent => :destroy
has_one :step_download, :dependent => :destroy
has_one :step_video, :dependent => :destroy
has_one :step_presentation, :dependent => :destroy
has_many :course_steps, :dependent => :destroy
has_many :courses, :through => :course_steps
end
class CourseEnrollment < ActiveRecord::Base
belongs_to :patient
belongs_to :course
end
class Patient < ActiveRecord::Base
belongs_to :user, :dependent => :destroy
has_many :enrollments, :dependent => :destroy
has_many :clients, :through => :enrollments
has_many :course_requests, :dependent => :destroy
has_many :course_enrollments, :dependent => :destroy
has_many :courses, :through => :course_enrollments
end
The usual approach is to nest these and have a compound sort of path, but how you route these things is often dependent on the level of context involved. For instance, is the display of a course driven by a user to the degree that the path should have the user in it, or is it a case of simply personalizing the course page?
Typically you see things like this:
resources :courses do |course|
course.resources :enrollments
course.resources :steps
end
There's usually a correlation between your has_many relationships and declaring an equivalent resources but not always.
Have a look at the generated routes using rake routes to see what the parameters will be called when passed to your controller, as well as what the expected controller name will be. You can customize the name of the controller by passing in a :controller option to the route.
Typically the last record in the path is passed in as :id whereas the prior ones are named, such as :course_id. This is a somewhat annoying inconsistency, so do be careful to check you're loading using the correct parameters.
If you need to display an individual step for a course, you definitely need to use the course_steps controller, logic being, each CourseStep object is a combo of one-course and one-step.