Retrieving all posts from a board that a user's subscribed to - ruby-on-rails

I'm currently setting up a feed from scratch where a user subscribes to multiple message boards and would receive all of the posts created under that board. This is how I have my code written so far:
class User < ApplicationRecord
has_many :subscriptions, dependent: :destroy
has_many :boards, through: :subscriptions
end
class Subscription < ApplicationRecord
belongs_to :user
belongs_to :board
end
class Board < ApplicationRecord
has_many :subscriptions, dependent: :destroy
has_many :subscribers, through: :subscriptions, source: :user
end
class Post < ApplicationRecord
belongs_to :board
belongs_to :user
end
When it comes time to display the posts is where I'm having problems as far as the proper approach. Would the simple solution be to setup another HMT association in the user model as so?
has_many :subscribed_posts, through: :boards, source: :posts
One immediate flaw I see in my approach is that the user would get their posts to show up including those of other users. Would the better solution be to create some sort of SQL query?

Yes, you can build another association to retrieve posts you need, but as you mentioned that would return also the users' posts too, so you have to put some conditions to prevent such behavior.
has_many :subscribed_posts, through: :boards, source: :posts, conditions: {["user_id != ?", id] }

Related

Over-writing ActiveRecord association macros

I'm building an API for an app that allows users to rate and favorite different ski mountains. At the moment, my associations are set up as follows:
class Mountain < ApplicationRecord
has_many :ratings
has_many :users, through: :ratings
has_many :favorites
has_many :users, through: :favorites
end
class Favorite < ApplicationRecord
belongs_to :mountain
belongs_to :user
end
class Rating < ApplicationRecord
belongs_to :mountain
belongs_to :user
end
class User < ApplicationRecord
has_many :ratings
has_many :mountains, through: :ratings
has_many :favorites
has_many :mountains, through: :favorites
end
The problem here is that User has many mountains through both ratings and favorites, but calling User.first.mountains will only give me mountains through ratings, since that's listed first. I'll need to utilize both in the app - any guidance here? Same deal for mountains - has many users through both ratings and favorites.
Thanks in advance for your help!

Rails ActiveRecord Associations that include "owner" role

I’m creating a chore tracker app as my first Rails project and I’m wondering if the associations I've created make sense or could be improved. Here are the details of the app:
A user makes a chore list and becomes the “owner”(i.e. “admin”) of
that list.
The owner can create/edit chores for the list. They can also “approve" other users to complete tasks on the list. These users can ONLY complete tasks.
The owner, along with the usual admin abilities, can also complete
tasks on a list that they own.
Owners can own multiple lists. Users can be approved to complete
tasks on multiple lists.
And here are the relationships I’ve roughed out that I’m looking for feedback on:
(Model)User
has_many :lists
has_many :owners, class_name: “List”, foreign_key: “list_id"
has_many :chores, through: :lists
(Model)List
has_many :users
has_many :chores
belongs_to :owner, class_name: “User”, foreign_key: “owner_id"
(Model)User_List
belongs_to :user
belongs_to :list
(Model)Chore
belongs_to :list
has_many :users, through: :lists
Any red flags? Thank you in advance!
I would do something like this:
# user.rb
class User
has_many :lists_users
has_many :lists, through: :lists_users
has_many :chores, through :lists
end
# list.rb
class List
has_many :lists_users
has_many :users, through: :lists_users
has_many :chores
end
# lists_user.rb
class ListsUser
belongs_to :user
belongs_to :list
# field (Representational, add it in database)
:user_role
- member (can view)
- collaborator (can mark complete)
- owner (can do everything)
end
# chore.rb
class Chore
belongs_to :list
end
NOTE: I changed the association model to ListsUser as per rails naming conventions.
Please let me know if i missed something.

Reblog a post when user repost from another user timeline

I need to enable a functionality like tumblr or similar blogs, where the the user can see the original poster (creator) and the user who reposted.
e.g. User A create a post1, User B 'repost' post1, User C discovered post1, because he follow user B or whatever. So user C must see 'post1, posted by User A, reposted by UserB... and so on if user C repost post1.
Currently user can like a micropost, but I also need to be able to 're_like' a micropost.
Firs I need to know the post belongs to reposter user.
I've seen some approach where we have different urls depending on user who reposted.
original ./post/1/
reposted ./post/1/reposted/18 (I guess 18 is repost_id or reposter_id)
My Models:
class User < ActiveRecord::Base
has_many :microposts, dependent: :destroy
has_many :likes
has_many :liked_posts, through: :likes, source: :micropost, dependent: :destroy
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :micropost
has_many :likes
class Micropost < ActiveRecord::Base
belongs_to :user
has_many :likes
has_many :liking_users, through: :likes, source: :user, dependent: :destroy
Rails 4.2.0

Many to many table rails

I'm trying to set up a many to many table using rails. I followed these instructions from the Rails Guides and believe I have the schema set up properly.
I would like to be able to see all reviews for a specific doctor.
models:
class Doctor < ActiveRecord::Base
has_many :reviews
has_many :users, through: :reviews
end
class Review <ActiveRecord::Base
belongs_to :user
belongs_to :doctor
end
class User < ActiveRecord::Base
has_many :reviews
has_many :doctors, through: :reviews
end
I'm able to successfully query doctor.users, user.doctors, and user.reviews. However when I try to query doctor.reviews I only see an empty proxy #<ActiveRecord::Associations::CollectionProxy []>
How can I see all reviews for a doctor?
You need to change:
class User < ActiveRecord::Base
has_many :reviews
has_many :doctors, through: :reviews
end
to:
class User < ActiveRecord::Base
has_many :reviews
has_many :doctors, through: :reviews, source: :doctor
end
What is happening is that user is looking for "doctors" inside of Reviews, but you have no method to retrieve "doctors" only "doctor". If you specify the source attribute, it will name your query "doctors" but it will look under "doctor" which in this case is defined. Rails tries to guess what it should be, and usually assumes correctly, but being more explicit may solve the problem in this case.

Rails: ignoring duplicates in an nested association

I have models User, Team, Document. There's a many-to-many relationship between Users and Teams, and a many-to-many relationship between Teams and Documents, using join tables called TeamMembership and TeamDocument respectively.
The relationships in my models look like this:
class Document < ActiveRecord::Base
has_many :team_documents, dependent: :destroy
has_many :teams, through: :team_documents
end
class User < ActiveRecord::Base
has_many :team_memberships, dependent: :destroy, foreign_key: :member_id
has_many :teams, through: :team_memberships
has_many :documents, through: :teams
end
class TeamDocument < ActiveRecord::Base
belongs_to :team
belongs_to :document
end
class TeamMembership < ActiveRecord::Base
belongs_to :team
belongs_to :member, class_name: "User"
end
class Team < ActiveRecord::Base
has_many :team_documents, dependent: :destroy
has_many :documents, through: :team_documents
has_many :team_memberships, dependent: :destroy
has_many :members, through: :team_memberships
end
The idea is that users can belong to many teams, a document can be associated with many teams, and users will only have access to documents that "belong" to at least one team that the user is a member of.
Here's the question: I can use User#documents to retrieve a list of all the documents that this user is allowed to view. But this will return duplicates if a document is viewable by more than one team which the user is a member of. How can I avoid this?
I know I can remove the duplicates after the fact with #user.documents.uniq, but as I will never want to include the duplicates in any case, is there a way I can just make #documents not include duplicates every time?
I don't have nested has_many :through like yours to test it, but I suspect using uniq option on your user association would help :
class User < ActiveRecord::Base
has_many :documents, through: :teams, uniq: true
end
You can add a default_scope on Document model:
class Document < ActiveRecord::Base
default_scope group: { documents: :id }

Resources