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 85,376+ developers who get early access to new tutorials, screencasts, articles, and more.

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