如何访问控制器或模型中的 current_user 变量?

How to access current_user variable in controller or model?

我在 userpost 模型之间有 1:N 关系。我想在 post 模型中访问 user_id。我通过访问 current_user 尝试了它,但它抛出找不到 current_user 变量。

我的用户模型class:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable, :validatable
  has_many :post
  validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
end

我的Post型号class:

class Post < ActiveRecord::Base
 belongs_to :user
 before_create :fill_data
 validates_presence_of :name, :message => 'Name field cannot be empty..'

 def fill_data
  self.is_delete = false
  self.user_id = current_user # here I am getting the error
 end
 end

我的Post控制器class

class PostController < ApplicationController
 before_action :authenticate_user!
 def index
  @post = Post.all
 end

 def new
  @post = Post.new
 end

def create
 @post = Post.new(post_params)
 if @post.save
  redirect_to action: 'index'
 else
  render 'new'
 end
end
.....
private
 def post_params
  params.require(:post).permit(:name,:user_id,:is_delete)
 end
end

我可以在 Post 控制器中访问 before_action :authenticate_user!,但不能在 post modelcontroller 中访问 current_user。我在 Post.fill_data. self.user_id 中做错了什么?

其余代码工作正常,我可以在 sqlite3 数据库中看到 :name and :is_delete 的新条目(当我在 Post class 中评论 self.user_id 行时).

编辑-1

我已经为 post

迁移 class
class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
     t.string :name
     t.boolean :is_delete
     t.references :user, index: true, foreign_key: true
     t.timestamps null: false
    end
  end
end

在 Rails 中,您的模型不应该知道应用程序的当前用户或任何其他状态。他们只需要了解自己以及与他们直接相关的对象。

另一方面,控制器知道当前用户。

因此,正确的做法是从 Post 中删除 fill_data 回调。并在控制器中执行:

class PostController < ApplicationController
  before_action :authenticate_user!
  def index
    @post = Post.all
  end

  def new
    @post = current_user.posts.build
  end

  def create
    @post = current_user.posts.build(post_params)
    if @post.save
      redirect_to action: 'index'
    else
      render 'new'
    end
  end

  private
  def post_params
    params.require(:post).permit(:name,:user_id,:is_delete)
  end
end

您还应该为数据库中的 is_delete 列设置默认值,但如果您想像专业人士一样使用它,请改用 enum

创建迁移 rails g migration AddStateToUsers 并填充:

class AddStateToUsers < ActiveRecord::Migration
  def change
    add_column :users, :state, :integer, default: 0
    remove_column :users, :is_delete
    add_index :users, :state
  end
end

然后我们使用 rails 枚举宏将状态映射到符号列表:

class Post
  enum state: [:draft, :published, :trashed]
  # ...
end

这让您可以 Post.trashed 将所有 post 放入回收站或 post.trashed? 检查特定 post 是否被回收站。

请注意,我使用 trashed 而不是 deleted,因为 ActiveRecord 内置了 deleted? 我们不想弄乱的方法。

您正在尝试使用 before_create 回调在 post 模型中添加 current_user.id。但更好的做法是使用这个

在posts_controller.rb

def new
  @post = current_user.posts.new
end

def create
  @post = current_user.posts.create(posts_params)
end

这将为当前用户创建一个 post。

你的fill_data方法是

def fill_data
  self.is_delete = false
end