Model User has many posts and can create post - ruby-on-rails

Hello i have trouble with logic. In my app users can create Posts and add them to favourites. The problem is in assiciations on Posts and Users. When User creates Post user_id is applied to posts table. How can i make associations when other user or this one add Post to favourite.

You need to create another table that will join a post and user. You can call that table favorites with 2 columns: post_id and user_id
class Favorite < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
has_many :favorites
has_many :favorite_posts, through: :favorites, source: :post
end
class Post < ActiveRecord::Base
belongs_to :user
has_many :favorites
has_many :favorited_by_users, through: :favorites, source: :user
end

You could create an new model/table for association. I would take a many to many relation for this.
Table: Bookmark
user_id | post_id
How a has many :through relationship in rails work is discriped here:
http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association

Related

How to reference a field in the join model of a has_many though Rails 5 relationship

I am working on an app where users have many quizzes and quizzes can have many users. I have set the relationships:
class User < ApplicationRecord
has_many :studies
has_many :quizzes, through: :studies
end
class Quiz < ApplicationRecord
has_many :studies
has_many :users, through: :studies
end
class Study < ApplicationRecord
belongs_to :user
belongs_to :quiz
end
I have a field in the Study table to store the score that the user made on the quiz, but I am unable to access the field. I have tried #quiz.studies.score and #quiz.study.score but Rails give me an undefined method. How to I access the field in a join model of a has_many though relationship?
#quiz.studies return the collection of studies. So you have to use first, last, each to get the score of the specific studies.
Try this:
#quiz.studies.first.score

Additional relation between records in Rails 5.0

I need your small advice help.
I have trivial models: Post and User.
A user has_many :posts and a post belongs_to :user. A post has one owner.
I need somehow add an additional relation: a post can have multiple contributors. A contributor is a user too. I need to be able to write something like this: #post.contributors (shows User records) and #user.contributed_to (shows Post records).
How do I do that?
You'll need many-to-many association here, because user has_many posts and posts has_many users.
To implement it, you need to create an additional model (for example, contribution with user_id and post_id columns)
class Contribution < ApplicationRecord
belongs_to :user
belongs_to :post
end
And your Post and User classes will contain something like this:
class Post
belongs_to :user
has_many :contributions
has_many :contributors, through: :contributions, source: :user
end
class User
has_many :posts
has_many :contributions
has_many :contributed_posts, through: :contributions, source: :post
end

Which Association Should I Use?

My app has 5 core models. I'm trying to figure out the best way to associate the models. How many tables should I build and which kind etc?
Here are the associations I would like to include and their respective models:
User
Has many boards
Has many lists
Has many cards
Has many comments
Board
Has many users
Has many lists
Has many cards
List
Belongs to board
Has many cards
Card
Belongs to board
Belongs to list
Has many comments
Comment
Belongs to card
Belongs to user
class User < ActiveRecord::Base
has_and_belongs_to_many :boards
has_many :lists, as: listable
has_many :cards, as: cardable
has_may :comments, as: commentable
end
class Board < ActiveRecord::Base
has_and_belongs_to_many :users
has_many :lists, as: listable
has_many :cards, as: cardable
end
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
end
class List < ActiveRecord::Base
belongs_to :listable, :polymorphic => true
has_many :cards, as: cardable
end
class Card < ActiveRecord::Base
belongs_to :cardable, :polymorphic => true
has_many :comments, as:commentable
end
To establish HABTM relation you have to create a table named 'users_boards'
As Board and User are having many to many relationship, there will be a new table for it, if you want HABTM you can use it.
User(id, name, other_attributes...)
Board(id, name,...)
List(id, name, user_id(fk),...)
Card(id, name, user_id(fk), list_id(fk), board_id(fk),...)
Comment(id, comment_msg, user_id(fk), card_id(fk),...)
Board_User(board_id(fk), user_if(fk)) --- M-M relation
Few attributes might change if there is a has_many through relation.
FK-- Foreign key, you can use has_many through depending on your requirements.
Using polymorphic associations has some limitations, so please do through it then decide to use a polymorphic association
http://codeblow.com/questions/pros-and-cons-for-ruby-on-rails-polymorphic-associations/

I am struggling with associations with my models on ruby on rails

I created a new rails application called imdb. I have created two models (via scaffolding) called User and Movie. I ran this in terminal.
rails g scaffold Movie title:string review:text location:string
rails g scaffold User name:string password_digest:string
I am finding it hard to imagine the associations that can be implemented into my application and need some help figuring this through.
We have these associations:
belongs_to,
has_one,
has_many,
has_many :through,
has_one :through,
has_and_belongs_to_many
I have so far thought that a 'user' can have many 'movies' and a 'movie' can have many 'users', but unfortunately my mind has gone blank! Help would be greatly appreciated.
Thanks.
This probably seems confusing to you because there may not be any direct relationship between movies and user. If you had a third model Review this may make more sense.
class Movie < ActiveRecord::Base
has_many :reviews, inverse_of: movie
end
class User < ActiveRecord::Base
has_many :reviews, inverse_of: user
end
class Review < ActiveRecord::Base
belongs_to :movie
belongs_to :user
end
I would create something like
Class User
has_many :movies
Class Movie
Belong_to :users
has_many :reviews :as => :reviewable
class Review
Belongs_to :movie
or
belongs_to :user
belongs_to :reviewable :polymorphic => true (this way this class can be reused later for more than movies and always written by user)
has_many :comments :as => :commentable etc.
It is similar to a case where A user may have many roles, and a role may have many users when you work with permissions (admin, user, guest, banned, etc...).
If I wanted to create a model that could be used in association with other models independently I would use a Polymorphic association as Richardlonesteen. ex: I want to have reviews written by users for books and movies, but a review belongs either to a book or movie and not both.
Your solution is to use the has_many :through association. You will have 3 models: User, Movie, and another model that will tie the relationship between the Users and the Movies. For example purpose we will call this third model Screening, but it can be anything else. When you create you Screening model, you will also need a migration with two columns user_id:integer movie_id:integer, and make sure you index them both.
Your user.rb
class User < ActiveRecord::Base
has_many :movies, :through => :screenings
has_many :screenings
attr_accessible :username
end
Your movie.rb
class Movie < ActiveRecord::Base
has_many :users, through => :screenings
has_many :screenings
attr_accessible :name
end
Your screening.rb
class Screening < ActiveRecord::Base
# attributes are :user_id and :movie_id
belongs_to :user
belongs_to :movie
end
Resulting with a relationship table that would look something like this
user_id | movie_id
------------------
1 | 1
------------------
1 | 2
------------------
2 | 1
------------------
3 | 2
Once you have this setup, you can fetch all movies of a user by doing #user.movies and vice-versa #movie.users. Rails will know how to find the associations.

How to reshare articles using association with the same table

I have a model called article with columns : id, title, content, user_id, i want to use association with the same table to say that article can be reshared by other users, so when a user reshare an article i think this is not necessary to copy the whole row of the origianl article, but just copy a reference to it , but how to do this using active record ?
remove the user_id from table articles, add a new association table call user_articles,
class User < ActiveRecord::Base
has_many :user_articles
has_many :articles, :through => :user_articles
end
class Article < ActiveRecord::Base
has_many :user_articles
has_many :user, :through => :user_articles
end
class User < ActiveRecord::Base
belongs_to :user
belongs_to :article
end

Resources