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

时间:2015-06-28 20:33:35

标签: ruby-on-rails ruby-on-rails-4 model-view-controller devise controller

我在1:Nuser模型之间有post个关系。我想访问user_id模型中的post。我是通过访问current_user来尝试的,但它正在投掷找不到current_user变量。

我的userModel类:

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

MyPostModel类:

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

MyPostController类

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!,但不能访问current_userpost model中的controller。我在Post.fill_data. self.user_id中做错了什么?

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

修改-1

我已经拥有post

的迁移课程
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

2 个答案:

答案 0 :(得分:1)

在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 enum宏将状态映射到符号列表:

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

这样,您就可以Post.trashed获取垃圾箱或post.trashed?中的所有帖子,以检查特定帖子是否已被删除。

请注意我使用trashed而不是删除,因为ActiveRecord构建了我们不想搞砸的deleted?方法。

答案 1 :(得分:0)

您正尝试使用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

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

您的fill_data方法将是

def fill_data
  self.is_delete = false
end