You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中created_by无法赋值current_user,数据库存为nil问题

解决Illustrator表created_by字段保存后为nil的问题

从你的描述来看,明明在调用@illustrator.save前已经把created_by设为current_user.id,但数据库里最终却是nil,这种情况大概率和模型回调、数据库字段定义、current_user的实现或者强参数配置有关,我帮你逐一排查:

1. 先检查Illustrator模型的回调逻辑

你没贴出Illustrator模型的代码,但如果模型里写了before_save、before_create这类回调,很可能在保存前把created_by给重置了。比如这种情况:

class Illustrator < ApplicationRecord
  before_save :clear_created_by

  private
  def clear_created_by
    self.created_by = nil # 这里会覆盖你之前设置的值
  end
end

如果有类似代码,要么修改回调的触发条件,要么直接删掉不必要的重置逻辑。

2. 确认数据库字段的定义是否正确

找到创建Illustrator表的迁移文件,检查created_by字段:

  • 类型是不是integer?毕竟current_user.id是整数,要是字段设成string类型,可能会导致隐性赋值失败
  • 字段是否存在?要是迁移里没加这个字段,保存时不会报错但也存不进值

正确的迁移写法应该是这样:

class CreateIllustrators < ActiveRecord::Migration[7.0]
  def change
    create_table :illustrators do |t|
      t.string :name
      # 其他字段...
      t.integer :created_by # 类型为integer,默认允许null
      t.timestamps
    end
  end
end

要是字段类型不对,就生成新迁移修改它。

3. 别让自定义的current_user干扰Devise的默认实现

Devise已经自带了current_user方法和对应的赋值逻辑,但你在ApplicationController里重写了current_user=:

private
def current_user=(user)
  @current_user = user
end

这可能会打乱Devise原本的用户状态维护逻辑。另外User模型里的cattr_accessor :current_user是类级别的属性,和Devise提供的请求级current_user完全不是一回事,很容易造成混淆。

建议把这两处自定义的current_user相关代码删掉,直接用Devise自带的current_user就好——毕竟你说保存前检查值是对的,但保不准回调或保存过程中因为这个自定义逻辑出问题。

4. 用日志输出确认值的变化

你可以在create动作里加几行打印代码,看看保存前后的值到底发生了什么:

def create
  @illustrator = Illustrator.new(illustrator_params)
  @illustrator.created_by = current_user.id
  
  # 控制台输出保存前的属性
  puts "保存前created_by的值: #{@illustrator.created_by}"
  puts "Illustrator所有属性: #{@illustrator.attributes.inspect}"
  
  if @illustrator.save
    # 保存后直接从数据库查,确认最终值
    saved_illustrator = Illustrator.find(@illustrator.id)
    puts "数据库里的created_by值: #{saved_illustrator.created_by}"
    
    redirect_to illustrator_path(@illustrator), notice: 'O autor foi criado com sucesso.'
  else
    render :new
  end
end

通过控制台的输出,你能清楚看到值在哪个环节被清空了。

5. 可选优化:用关联代替直接赋值id

如果Illustrator和User模型加个关联,代码会更清晰,还能避免类型不匹配的问题:

# 在Illustrator模型里添加关联
class Illustrator < ApplicationRecord
  belongs_to :created_by_user, class_name: 'User', foreign_key: 'created_by', optional: true
end

# 然后在create动作里直接赋值对象
@illustrator.created_by_user = current_user

这种方式更符合Rails的关联设计,也能减少手动处理id的麻烦。

按照上面的步骤一步步排查,应该能找到问题所在。

内容的提问来源于stack exchange,提问作者Morgana Borges

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:07:36