has_one :through association Rails 3 - ruby-on-rails

I'm working on a site which has members. Each member has a subscription. For a subscription a member needs to choose a plan of which there are 3.
Is this correct way to do the association
class Member < ActiveRecord::Base
has_one :plan, :through => :subscription
end
class Subscription < ActiveRecord::Base
belongs_to :member
has_many :plans
end
class Plan < ActiveRecord::Base
belongs_to :subscription
end
Then maybe something like this
member.plan
would be the plan a member is subscribed to.

If a member can belong to one plan at a time you can redo your models as follows:
class Member < ActiveRecord::Base
has_one :subscription
has_one :plan, :through => :subscription
end
class Subscription < ActiveRecord::Base
belongs_to :member
belongs_to :plan
end
class Plan < ActiveRecord::Base
belongs_to :subscription
has_many :members
end
Other solution is to avoid the Subscription model altogether by adding a plan_id column to members table.
# has a column called plan_id
class Member < ActiveRecord::Base
has_one :plan
end
class Plan < ActiveRecord::Base
has_many :members
end

Related

Ruby: how to find to which user belongs payment in has many through relationship

So I have this:
User:
has_many: subscriptions
Subscription:
belongs_to: user
has_many: payments
Payment:
belongs_to: subscription
If i have a Payment id, how can I find a User?
As Nick mentioned, Payment.find(id).subscription.user will work just great. If this is something you'll be doing often, I'd recommend adding a has_one :through relationship as well.
class Payment < ApplicationRecord
belongs_to :subscription
has_one :user, through: :subscription
end
And then you can directly reference Payment.find(id).user!
If you declare an indirect association from Payment to User you can get it directly:
class User < ApplicationRecord
has_many :subscriptions
has_many :payments, through: :subscriptions
end
clas Subscription < ApplicationRecord
belongs_to :user
has_many :payments
end
class Payment < ApplicationRecord
belongs_to :subscription
has_one :user, through: :subscription
end
user = User.joins(:payments).where(payments: { id: [id] }).first
# or
payment = Payment.eager_load(:user).find(id)
user = payment.user

Association between 3 models

I would like a user be able to create a course(so it should belong to one user) and also be able to join another course that it haven't created by him.What is the proper associations between the course and the user ? I want to make the following model associations:
Class User < ActiveRecord::Base
has_many :courses
has_many :comments ,through: :courses
end
Class Course < ActiveRecord::Base
has_and_belongs_to_many :users #here i am not sure
has_many :comments
end
Class Comment < ActiveRecord::Base
belongs_to :courses
end
I think what you should be able to do something like:
Class User < ActiveRecord::Base
has_many :courses
has_many :course_users
has_many :subscribed_courses, through: :course_users, source: :course # I think you should be able to do foreign_key: :course_id, class_name: 'Course'
has_many :comments ,through: :courses
end
Class Course < ActiveRecord::Base
belongs_to :user
has_many :course_users
has_many :participants, through: :course_users, source: :user # I think you should be able to do foreign_key: :user_id, class_name: 'User'
has_many :comments
end
Class Comment < ActiveRecord::Base
belongs_to :courses
end
#course_users is a join table for courses and users
class CourseUser < ActiveRecord::Base
# inside here you could have several other connections e.g grade of a user in a course within this join model
belongs_to :user
belongs_to :course
end
If I'm understanding what you're saying - you need to have a third model - you can call it enrollment
For Course you would use belongs_to :user if each course is created as a user.
Your Enrollment model with have two HABTAM
Class Enrollment < ActiveRecord::Base
has_and_belongs_to_many :users
has_and_belongs_to_many :courses
end
(An Aside, if a course is going to be offered more than once, you'll have to add an additional model for each instance of the course and the enrollment will belong to that model, and not courses)

Rails activerecord deep eager loading

Here is my models:
class User < ActiveRecord::Base
has_many :products
has_many :comments
end
class Product < ActiveRecord::Base
belongs_to :user
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :product
end
I need to get comment records from current user products only
How do I do that? thanks
If we move the relationships to use a has_many: comments, through: products you can probably get what you're after:
class User < ActiveRecord::Base
has_many :products
has_many :comments, through: products
end
class Product < ActiveRecord::Base
belongs_to :user
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :product
end
Now you can do user.comments.
The rails docs are here, which say:
A has_many :through association is often used to set up a many-to-many
connection with another model. This association indicates that the
declaring model can be matched with zero or more instances of another
model by proceeding through a third model. For example, consider a
medical practice where patients make appointments to see physicians.

Model associations for a contest

I'm new to rails and working on an app that has the following situation:
Users have skills (e.g rafting, dancing)
Users participate in contests
Contest measures multiple skills
At the end of each contest, each user gets a score (e.g dancing: 5, rafting: 4)
Whats the best way to model this ?
Thanks,
This got nasty :s At the end I was actually not sure if this is the right way
class Skill < ActiveRecord::Base
has_many :skill_scores
has_many :user_skills
end
class UserSkill < ActiveRecord::Base
belongs_to :user
belongs_to :skill
end
class SkillScore < ActiveRecord::Base
belongs_to :user
belongs_to :contest
belongs_to :skill
end
class User < ActiveRecord::Base
has_many :skills
has_many :contests, :through => :contest_participations
has_many :skill_scores
end
class Contest < ActiveRecord::Base
has_many :users, :through => :contest_participations
has_many :skill_scores
end
class ContestParticipation < ActiveRecord::Base
belongs_to :user
belongs_to :contest
end

has_many inheritance

I have a model called company that has_many users then users belongs_to company.
class Company < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :company
end
If something belongs to users will it also belong to company?
You have to use has_many :through association for this.
class Comment < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
belongs_to :company
has_many :comments
end
class Company < ActiveRecord::Base
has_many :users
has_many :comments, :through => :users
end
Now you can do the following:
c = Company.first
c.users # returns users
c.comments # returns all the comments made by all the users in the company

Resources