Ask A Question

Notifications

You’re not receiving notifications from this thread.

Retrieve all Project Threads where a given users has posted a Project Post

Lauro asked in Ruby

A user belogns to a ProjectThread. And a ProjectThread has_many Users through ProjectPosts.

On the Project Thread Index I want to display only threads where a given users has posted a Project Post.

How would I go about doing that?

class ProjectThreadsController < ApplicationController
  def index
        @project_thread = if current_user.project_posts.any?
                           ProjectThreads.all
                      end
  end
Reply

There might be a slicker way, but this works:

ProjectThread.find(current_user.project_posts.pluck(:project_thread_id).uniq)

This will select all the current_users project_posts, pluck the ID's of the project_thread_id, then call uniq to ensure that if a user had multiple posts in a single thread, you won't get duplicate threads.

And just to make sure, your description of how you have your models setup doesn't sound right. They should be like this:

# user model
class User < ApplicationRecord
  has_many :project_threads, through: :project_posts
  has_many :project_posts
end

# project_thread model
class ProjectThread < ApplicationRecord
  has_many :users, through: :project_posts
  has_many :project_posts
end

# project_post model
class ProjectPost < ApplicationRecord
  belongs_to :user
  belongs_to :project_thread
end

Check: http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

Reply

Jacob thanks! ProjectThread.find(current_user.project_posts.pluck(:project_thread_id).uniq) worked!

How would would I create a private method to prevent other users from accessing Project Threads that dont belong to them?

I currently have something like this:

  def require_permission
      if current_user != ProjectThread.friendly.find(params[:id]).user
        redirect_to root_path
      end
    end

But this only works if the user is the ProjectThread owner.

And currently I have my models setup like this. it seems to be working okay.

class User < ApplicationRecord
  has_many :project_threads
  has_many :project_posts
end

class ProjectThread < ApplicationRecord
  belongs_to :user, optional: true
  has_many :project_posts
  has_many :users, through: :project_posts
end

class ProjectPost < ApplicationRecord
  belongs_to :user, optional: true
  belongs_to :project_thread, optional: true
end
Reply

You need another table that handles assignments to threads.

# project_thread_access model
# you'll need user_id and project_thread_id columns in this model
belongs_to :project_thread_accessable, :polymorphic => true

# project_thread model
has_many :project_thread_access, as: :project_thread_accessable

# user model
has_many :project_thread_access, as: :project_thread_accessable

This would let you do something like:

current_user.project_thread_access which would return a list of project_threads that user has been assigned to.

Now, you can do something like:

def show
  redirect_to root_url, alert: "Sorry, but you do not have access to this thread" unless current_user.project_thread_access.pluck(:project_thread_id).include?(params[:id])
end

*updated redirect - alert needs to be before the condition

I haven't tested this, so it may need some tweaking - but you should get the idea

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 76,990+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more. Icons by Icons8

    © 2023 GoRails, LLC. All rights reserved.