非Rails环境下使用ActiveRecord更新PostgreSQL记录报错排查
问题原因
你的user_logins表未定义主键,而ActiveRecord默认依赖主键生成合法的更新SQL语句。从错误日志里的WHERE "user_logins"."" IS NULL可以看出,ORM无法找到主键列,导致生成了无效的SQL语法。
解决方案
有三种可行的解决方式,根据需求选择:
1. 给表添加主键列(推荐)
修改PostgreSQL表结构,添加标准的自增主键列,这是ActiveRecord最适配的方式:
ALTER TABLE user_logins ADD COLUMN id SERIAL PRIMARY KEY;
执行这条SQL后,模型无需修改,原有的update代码就能正常工作。
2. 在模型中指定现有列作为主键
如果不想修改表结构,可以利用已有的user_id列(它已经是UNIQUE NOT NULL)作为主键,在模型中声明:
class UserLogin < ActiveRecord::Base self.primary_key = :user_id end
这样ActiveRecord会用user_id定位记录,生成正确的更新SQL。
3. 使用批量更新跳过对象实例化
如果不需要先获取对象实例,直接通过where条件批量更新,这种方式更高效,也不依赖主键:
def update_last_visited(user_token) # update_all返回更新的行数,>0表示成功更新 UserLogin.where(token: user_token).update_all(last_visit: Time.now.utc) > 0 end
验证修改
以方案2为例,修改模型后运行你的最小复现代码,update_last_visited方法会生成正确的SQL:
UPDATE "user_logins" SET "last_visit" = $1 WHERE "user_logins"."user_id" = $2
不会再出现语法错误。
内容的提问来源于stack exchange,提问作者Lars Kakavandi-Nielsen
相关产品推荐
相关产品推荐

