How to create a correct association - ruby-on-rails

Tell me how to build a relationship between the models as follows:
- You can have a lot of posts
- Other users can write to each other positions on the wall (as in social networks, namely, when you can itself create a record or you can create it on another user page.

You should at least try to do it yourself, but here is solution:
User model:
User (id, name)
has_many :posts
has_many :comments
has_many :commented_posts, through: :comments
Post model:
Post (id, content, user_id)
belongs_to :user
has_many :comments
Comment model:
Comment (id, content, post_id, user_id)
belongs_to :user
belongs_to :post

If you refereing to posts as medium with which user can tag other users, so that the post can appear on their walls.
You can definetly use posts to write to other people walls. Thats how any social platform works, same post can act as standalone post like a blog user is publishing for his followers or in particular community.
I a social feed like platform, tags the users on the post is the only way to push the post on wall feed of any user.
So Here we can have the following entities.
User
class User < ActiveRecord::Base
has_many :usertags
has_many :posts
end
Post
class Post < ApplicationRecord
has_many :usertags, as: :usertagable
belongs_to :user
has_many :comments ,:as => :commentable
end
Usertag
class Usertag < ApplicationRecord
belongs_to :user
belongs_to :usertagable, :polymorphic => true
end
i have build polymorphic relations for usertags as you may extend the current schema to involves comments on the posts as well like the following comment model, which can be served using polymorphic relations.
class Comment < ApplicationRecord
# all the relations for the comment
belongs_to :user
belongs_to :post
belongs_to :commentable, :polymorphic => true
has_many :comments, :as => :commentable
has_many :usertags, as: :usertagable
end
Comment in turn belong to a users/author, post to which comment is attached, comment can also be commented so it can also belong to commentable. Also comment can have user mentioned as wells like posts can.
A social feed like platform, tags the users on the post is the only way to push the post on wall feed of any user.
Now you can easily fetch all the posts belonging to particular user along with usertagged, comments, auther of comments.
post_list = Post.eager_load(:followers, :user, :communities, :usertags => :user, :comments => [:usertags => :user]).select("*").where("user.id is ?", :user_id)
Hope this helps
Thanks.

Related

How to get all childs active-storage attachments in rails?

let's say there are 2 models.
user model:
has_many :posts
post model:
belongs_to :user
has_many_attached :files, dependent: :destroy
what I want is simply all files of the user. something like:
has _may :post_files , through: posts, class_name: "XXX"
or any other way which can give me all the files of the user.
so I want all files of all posts which belong to the user. like user.post_files
thank you all for your answers. I found the solution.
has_many_attached :files actually sets two has_many relationships:
has_many :files_attachments and
has_many :files_blobs
So in user.rb (parent model) we can simply have:
has_many :files_attachments, through: :posts
and in this way, you can have user.files_attachments to get all files of posts for one user.
Here is how the structure should be
user.rb <-- User model
has_many :posts
post.rb <-- Post model
belongs_to :user
has_many_attached :files
this way you can do
Post.post_files
or
Post.with_attached_files.find(params[:id])
In conclusion.
The attachments belong to the Post, not to the User, so there is no need to make any call to User model
Your post model acts as an xref table between users and attached files right?
You have defined a user as having many posts and a post as having many attached files. Using has_many through: will allow a user to see all the attached files for a post
user model:
Class User < ...
has_many :posts
has_many attached_files, through: :posts
post model:
Class Post < ...
belongs_to :user
has_many_attached :files, dependent: :destroy
Class AttchedFiles < ...
belongs_to :post
This enables you to do things like
User.first.attached_files
Which will return all the attached files for the user returned by the User.first declaration
Which I believe is what you were looking for

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

Model User has many posts and can create post

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

What is the right way to set up a many to many association in Rails

So I've got three models in my app, a User, Review and a Movie model. A user can review many movies (one per movie), a Movie can have many reviews from many users. Their connection is a review.
Am I doing the following setup right?
class Movie < ActiveRecord::Base
has_many :reviews, :through => :users
end
class Review < ActiveRecord::Base
belongs_to :user
belongs_to :project
end
class User < ActiveRecord::Base
has_many :reviews, :through => :movies
end
I'm hoping I can do something like:
User.reviews (which would give me back the user's reviews and the corresponding id of the movie which the review relates to)
Thanks
I believe this is the approach you should be taking
class User < ActiveRecord::Base
has_many :reviews
has_many :movies, :through => :reviews
end
class Review < ActiveRecord::Base
belongs_to :user
belongs_to :movie
end
class Movie < ActiveRecord::Base
has_many :reviews
has_many :users, :through => :reviews
end
You would also want to validate uniqueness in the model Review and/or enforce uniqueness on the join-table to only allow a single user per movie. It's up to you if you want to take this UQ constraint into the schema as well (DHH says 'Yes', I say 'the slathering of dumb persistance' is a 'No no'...)
User.reviews will give you the 'join records', i.e. along the lines of <Review user_id=x, movie_id=y> Certainly, you'd have a lot more columns on the join table pertaining to the review, such as :summary, :content etc. It's easy enough to access the movie from a review, i.e. Movie.find_by_id(User.reviews.last.movie_id).title

Nested associates the rails way

I'm fairly new to Rails and I'm trying to gain a better understanding of how to be leverage the Rails framework for my associations.
While it's not specific for my app, the structure is similar -- for my example, I'll use the standard blog associates.
Example Models:
class Author < ActiveRecord::Base
has_many :posts, :through => :posts
end
class Post < ActiveRecord::Base
belongs_to :author
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :post
end
My challenge is that I want to select all comments that belong to a specific author. I understand how to reference post and author elements that are associated with a specific post:
comment_author = Comment.first
puts comment_author.post.author.name
But as I stated I'm trying to select all comments that belong to a specific author. I could accomplish this by doing a find_by_sql, but I want to ensure db independence and I want to do this the "Rails way."
Thanks!
You can use the has_many :through assocication:
class Author < ActiveRecord::Base
has_many :posts
has_many :comments, :through => :posts
end
#Femaref provided the exact answer to your question and you should accept it. Mine is merely a complement.
If an author can leave comments on posts, here is what you might want to do:
class Author
has_many :posts
has_many :comments
has_many :responses, through: :posts, source: :comments
end
class Post
belongs_to :author
has_many :comments
end
class Comment
belongs_to :author
belongs_to :post
end
To get all the comments left by sophia: sophia.comments
To get all the comments left on sophia's posts: sophia.responses
See the options for has_many (especially through and source)

Resources