How to setup model associations in Rails - ruby-on-rails

I'm trying to create associations for three models in my Rails application. In the application a User can access courses which have videos. How would I model this?
This is what I currently have:
class User < ApplicationRecord
has_many :courses
has_many :videos, through: :courses
end
class Course < ApplicationRecord
belongs_to :user
has_many :videos
end
class Video < ApplicationRecord
belongs_to :course
belongs_to :user
end
Is this the correct way to model these associations for what I want the application to be able to achieve?

Normally, this would look something like:
class UserCourse < ApplicationRecord
belongs_to :user
belongs_to :course
end
class User < ApplicationRecord
has_many :user_courses
has_many :courses, through: :user_courses
has_many :videos, through: :courses
end
class Course < ApplicationRecord
has_many :user_courses
has_many :users, through: :user_courses
has_many :videos
end
class Video < ApplicationRecord
belongs_to :course
has_many :users, through: :course
end
That should let you do:
#user.courses
#user.videos
#course.users
#course.videos
#video.course
#video.users
(Assuming, of course, you've instantiated each of the above variables and you have associated records.)

Related

How to fix this error "HasManyThroughCantAssociateThroughHasOneOrManyReflection" in rails 5?

I Have created simple rails apps and I got error "HasManyThroughCantAssociateThroughHasOneOrManyReflection" that shown in rails admin when I want to post an Image.
this my code:
can anyone Help me to solve it ?
class ProductInvest < ApplicationRecord
belongs_to :product
has_many :pictures, through: :product
end
class Product < ApplicationRecord
has_many :pictures
has_many :Product_invests
end
class Picture < ApplicationRecord
belongs_to :product
has_many :Product_invests, through: :product
end
Your associations aren't setup correctly. Try this instead:
class ProductInvest < ApplicationRecord
has_many :products
has_many :pictures, through: :products
end
class Product < ApplicationRecord
belongs_to :pictures
belongs_to :product_invests
end
class Picture < ApplicationRecord
has_many :products
has_many :product_invests, through: :products
end
You can get more information here: RubyGuides

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)

How to correctly write my relationship/associations in Rails?

I have 4 Models and i am not sure what is the correct way to write my relationships/associations.
class User < ActiveRecord::Base
has_many :boards
has_many :lists
has_many :cards
end
class Board < ActiveRecord::Base
belongs_to :user
has_many :lists
end
class List < ActiveRecord::Base
belongs_to :user
belongs_to :board
has_many :cards
end
class Card < ActiveRecord::Base
belongs_to :user
belongs_to :list
end
If you want to be more explicit about your relationships, feel free to do the following (preferred in most every case):
class User < ActiveRecord::Base
has_many :boards, inverse_of: :user, dependent: :destroy
has_many :lists, inverse_of: :user, dependent: :destroy
has_many :cards, inverse_of: user, dependent: :destroy
end
class Board < ActiveRecord::Base
belongs_to :user, inverse_of: :boards
has_many :lists, inverse_of: :board
end
class List < ActiveRecord::Base
belongs_to :user, inverse_of: :lists
belongs_to :board, inverse_of :lists
has_many :cards, inverse_of :list
end
class Card < ActiveRecord::Base
belongs_to :user, inverse_of: :cards
belongs_to :list, inverse_of :cards
end
Finally, make sure any of your models that are dependent on another (e.g. Board belongs_to User) have the appropriate foreign key in their table. So, for example, Board will need to have a user_id foreign key to correctly create the association.
You can create a migration for any of those entities if you haven't already like so:
rails generate migration AddUserRefToBoards user:references

Modeling "Likes" in rails HABTM vs HM/BT

What would be the best method to model "likes" in rails for my app. I could either to the following:
class User < ActiveRecord::Base
has_many :things
has_many :likes
has_many :liked_things, through: :likes, source: :thing
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :thing
end
class Thing < ActiveRecord::Base
belongs_to :user
has_many :likes
has_many :liking_users, through: :likes, source: :user
end
Or
class User < ActiveRecord::Base
has_many :things
has_and_belongs_to_many :things
end
class Thing < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :users
end
What approach would be best and why? I plan to have an activity feed in my app as well, if that helps determine the best approach.
The answer to this question depends on whether or not Like will ever have any attributes or methods.
If its only purpose of existence is to be the HABTM relationship between Users and Things, then using the has_and_belongs_to_many relationship would suffice. In your example, having has_many and belongs_to is redundant. All you would need in this case is:
class User < ActiveRecord::Base
has_and_belongs_to_many :things
end
class Thing < ActiveRecord::Base
has_and_belongs_to_many :users
end
On the other hand, if you anticipate that a Like will have an attribute (e.g. maybe someone will really like something, or love it, etc.) then you can do
class User < ActiveRecord::Base
has_many :likes
has_many :liked_things, through: :likes, source: :thing
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :thing
end
class Thing < ActiveRecord::Base
has_many :likes
has_many :liking_users, through: :likes, source: :user
end
Note that I removed has_many :things and belongs_to :user as they are redundant.

twitter model associations in rails

I am trying to build a twitter like data model in rails. This is what I have come up with.
class User < ActiveRecord::Base
has_many :microposts, :dependent => :destroy
end
class Micropost < ActiveRecord::Base
belongs_to :user
has_many :mentions
has_many :hashtags
end
class Mention< ActiveRecord::Base
belongs_to :micropost
end
class Hashtag < ActiveRecord::Base
belongs_to :micropost
end
Should I be using a has_many through association somewhere or is this accurate?
Edit: The final twitter MVC model.
class User < ActiveRecord::Base
has_many :microposts, :dependent => :destroy
userID
end
class Micropost < ActiveRecord::Base
belongs_to :user
has_many :link2mentions, :dependent => :destroy
has_many :mentions, through: :link2mentions
has_many :link2hashtags, :dependent => :destroy
has_many :hashtags, through: :link2hashtags
UserID
micropostID
content
end
class Link2mention < ActiveRecord::Base
belongs_to :micropost
belongs_to :mention
linkID
micropostID
mentionID
end
class Mention < ActiveRecord::Base
has_many :link2mentions, :dependent => :destroy
has_many :microposts, through: :link2mentions
mentionID
userID
end
Edit 2: A concise and accurate explanation
http://railscasts.com/episodes/382-tagging?view=asciicast
If two microposts use the same hashtag, you probably don't want to create two database records for that hashtag. In this case you would use has_many through:
class Hashtagging < ActiveRecord::Base
belongs_to :micropost
belongs_to :hashtag
end
class Hashtag < ActiveRecord::Base
has_many :hashtaggings
has_many :microposts, through: :hashtaggings
end
class Micropost < ActiveRecord::Base
...
has_many :hashtaggings
has_many :hashtags, through: :hashtaggings
end
When you create the Hashtagging migration, make sure it has the micropost_id and hashtag_id columns.

Resources