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.