简体   繁体   中英

Ruby - How can i get current user in Model?

I want to list the current user comments wrote to the book and waiting for approval. I tried where(user_id: current_user.id) but it's not working. How can i use current_user in Model?

Version: Rails 6

Comment model.

class Comment < ApplicationRecord
  validates :title, presence: true
  validates :content, presence: true

  belongs_to :book
  belongs_to :user

  scope :approved, -> {where(status: true)}
  scope :waiting_for_approval, -> {where(status: false).where(user_id: current_user.id)}
end

User model

class User < ApplicationRecord
  before_create :set_username
  
  has_many :books
  has_many :comments
  has_many :offers

  validates_length_of :set_username, 
  :minimum => 5, :maximum => 50, 
  presence: true,
  uniqueness: true
 
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  def set_username
    self.username = self.email.split(/@/).first
  end
end

Book Model

class Book < ApplicationRecord
  validates :title, presence: true
  validates :author, presence: true

  belongs_to :user
  has_many :comments
  has_many :offers

  scope :can_be_listed, -> {where(status: true)}
  scope :can_be_tradable, -> {where(status: true, tradable: true)}
end

Instead of trying to pass the user id, this would in fact just be a simple relation on the user model

class Comment < ApplicationRecord
  scope :waiting_for_approval, -> { where(status: false) }
end

class User < ApplicationRecord
  has_many :comments
end

Then you could get the waiting for approval for the current user... in your controllers or views... as

current_user.comments.waiting_for_approval

使用带参数的范围

scope :waiting_for_approval, -> (user_id) { where(status: false, user_id: user_id) }

The easiest way to use current_user in the model would be to pass it as parameter.

class Comment < ApplicationRecord
  scope :by, ->(user) { where(user_id: user.respond_to?(:id) ? user.id : user) }
  scope :waiting_for_approval, -> { where(status: false) }
end

Then do the following in your controller:

comments = Comment.by(current_user).waiting_for_approval

However I suggest using the answer of SteveTurczyn if possible.

you have to set current_user as a cattr_accessor of User class. Then you can access it in any model by calling User.current_user .

You can follow these steps.

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  before_action :set_current_user

  private

  def set_current_user
    User.current_user = current_user
  end
end
# app/models/user.rb

class User < ApplicationRecord
  # your codes ...

  cattr_accessor :current_user
end
# app/models/comment.rb

class Comment < ApplicationRecord
  # your codes ...

  scope :waiting_for_approval, -> { where(status: false).where(user_id: User.current_user.id) }
end

Happy Coding :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM