简体   繁体   中英

Many-to-Many Association in Rails

I am creating a Rails project and really struggle with basic nested forms and associations and could use some help getting this started. My project needs to have one has_many, one belongs_to, and at least 2 has_many:through relationships (including a many-to-many implemented with the has_many through association).

So I would like to create an app that allows a user to keep track of all the movies or shows that they want to watch. I thought of this because people are constantly telling me new shows/ movies to watch and I add them to a list in my notes app on my phone - so why not create an app for it!

I am really struggling with how to set up the models. Here is what I have done so far, please let me know how I could finish or fix them in any way. I also have no idea how to really create a Join table for this association. Any and all help is appreciated!

User (email and password)
has_many:apps
has_many:movies
has_many:shows
has_many:movies, through: :apps
has_many:shows, through: :apps

App (Exs: Netflix, Hulu, Amazon Prime) (app name)
belongs_to:user
belongs_to:movie
belongs_to:show

Movie (movie title, app, genre, status)
belongs_to:app
has_many:users

Show (show title, app, genre, seasons/episodes (optional) and status)
belongs_to:app
has_many:users

Let me know some thoughts on how I can set these up!

Your models land pretty far off the mark. Lets start with the relation between users and what you are calling "apps" - a more specific term thats not as overlaiden with other connotations in Rails would be "streaming service" or "content provider".

class User < ApplicationRecord
  # ...
  has_many :subscriptions
  has_many :streaming_services,
    through: :subscriptions
end

class Subscription < ApplicationRecord
  belongs_to :user
  belongs_to :streaming_service
end

# for example: Netflix, Hulu, Amazon Prime
class StreamingService < ApplicationRecord
  has_many :subscriptions
  has_many :users,
    through: :subscriptions
end

This setup lets you create a many to many assocation between users and the streaming services that they have without creating duplicate data in the form of strings.

Then setup the assocations between the services and the content:

# for example: Netflix, Hulu, Amazon Prime
class StreamingService < ApplicationRecord
  # ...
  has_many :movies
end

class Movie < ApplicationRecord
  belongs_to :streaming_service
end

class User < ApplicationRecord
   # ...
   has_many :available_movies,
     through: :streaming_services,
     source: :movies
end

For the sake of simplicity in whats already probally over your head lets just stick to movies for now.

If you want to create a watchlist of items you want to create a separate model that joins users movies:

# rails g model WatchlistItem user:belongs_to movie:belongs_to status:integer{default:0}
class WatchlistItem < ApplicationRecord
  enum status: [:pending, :watching, :completed]
  belongs_to :user
  belongs_to :movie
  has_one :streaming_service, through: :movie
end

class Movie < ApplicationRecord
  belongs_to :streaming_service
  has_many :watch_list_items
  has_many :users, through: :watch_list_items
end

class User < ApplicationRecord
  # ...
  has_many :watch_list_items
  has_many :movies, through: :watch_list_items
end

watchlist_items is where you would store the status. Not on the movie itself as that would change it for all users.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM