Home > OS >  How to limit the CRUD content of Rails' current_user
How to limit the CRUD content of Rails' current_user

Time:03-28

I'm making a task management system and building a user registration and login system without relying on the devise gem. Currently I am facing a challenge, I want each user (called current_user when logging in) can only see the tasks they created (listed on the homepage/index), including that they can only edit or delete their own tasks. To this end, I added a before action def find_user_task to the controller, but it is completely invalid. Please tell me, what am I missing in principle?

This is part of ApplicationController

helper_method :user_signed_in?, :current_user

  private
    def user_signed_in?
      session[:random2022] != nil
    end

    def current_user
      if user_signed_in?
        User.find(session[:random2022])
      else
        nil
      end
    end

    def check_login!
      if not user_signed_in?
        redirect_to "/users/sign_in"
      end
    end

This is part of TasksController

  before_action :find_task, only: [:show, :edit, :update, :destroy]
  before_action :check_login!, except: [:index, :show]
  before_action :find_user_task, only: [:edit, :update, :destroy, :publish]

private
  def find_task
    @task = Task.find(params[:id])
  end

  def task_params
    p = params.require(:task).permit(:name, :due_date, :note, :priority)
    p[:status] = params[:task][:status].to_i
    return p
  end

  def find_user_task
        @task = Task.find(params[:id])
        @task = Task.find_by(id: params[:id], user_id: current_user.id)
        # @task = current_user.tasks.find(params[:id])
    end
end

This is part of Model Task

class Task < ApplicationRecord
  validates :name, :note, :due_date, :status, :priority, presence: true
  has_many :category_tasks
  has_many :categories, through: :category_tasks
  belongs_to :user, foreign_key: true, optional: true

This is part of Model User

require 'digest'

class User < ApplicationRecord
  validates :email, presence: true, uniqueness: true
  validates :password, confirmation: true, length: { minimum: 4 }, presence: true
  validates :role, presence: true, uniqueness: true
  has_many :tasks, dependent: :destroy

CodePudding user response:

hope I can help you here... first of all, here on this piece of code:

    @task = Task.find(params[:id])
    @task = Task.find_by(id: params[:id], user_id: current_user.id)

Your second line overrides the first, so you can remove the first one. About your problem, I would suggest you to do that based on your models and relationships... it's easier (and better) than to handle it in controller. The thing is you wanna make sure that a task belongs to a user (and which can have N tasks). Before you create a task, you make sure to set the user_id for that task as the current_user.id. It would be somthing like that:

class User < ApplicationRecord
  has_many :tasks
end

and for your task model:

class Task < ApplicationRecord
  belongs_to :user
end

Then, on your create action on your tasks controller (or wherever you do that), be sure to set the user_id for your current_user:

@task.user_id = current_user.id

If you still didn't created the foreign_key (user_id) for a task, just make a migration, something like this:

rails g migration AddUserIdToTask user_id:integer
rails db:migrate

Then, if you do it correctly, you can get the tasks for a specific user just acessing them by the relationship: user.tasks (or, in your case):

@tasks = current_user.tasks

For debugging and testing that, rails console is your friend... create a task for a user, then check on console if the user_id is set correctly. Then try to load that user.tasks and see if it brings them as you expected. Go checking it step by step.

  • Related