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

Ruby on Rails中Model实例值不更新问题求助

Rails博客应用:更新用户posts_counter后User.all无法获取最新值

我正在用Ruby on Rails构建博客应用,写了一个方法用于用户新增Post时更新其posts_counter字段,代码如下:

class Post < ApplicationRecord
  belongs_to :author, class_name: 'User', foreign_key: 'user_id'
  has_many :comments
  has_many :likes

  after_save :update_user_counter

  validates :title, presence: true, length: { maximum: 250 }
  validates :comments_counter, :likes_counter, numericality: { only_integer: true, greater_than_or_equal_to: 0 }

  after_initialize do |post|
    post.comments_counter = 0
    post.likes_counter = 0
  end

  def update_user_counter
    author.increment!(:posts_counter)
  end

  def recent_5_comments
    comments.order(created_at: :desc).limit(5)
  end
  
  private :update_user_counter
end

测试步骤:

  1. 确认目标用户的posts_counter初始值为0;
  2. 通过User.find(1)获取用户并存储为变量;
  3. 为该用户创建新Post;
  4. 调用用户变量,posts_counter显示为1;
  5. 执行User.all查询,该用户的posts_counter仍显示为0。

问题原因

这是Rails控制台的查询缓存机制导致的:

  • increment!方法会直接更新数据库中的posts_counter,同时更新内存中author对象的属性,所以你存储的用户变量能看到最新值;
  • 若之前执行过User.all,Rails会缓存该查询结果,后续重复执行时会直接返回缓存的旧数据,而非重新查询数据库。

解决方法

1. 清除查询缓存

在控制台执行以下命令清除全局查询缓存:

ActiveRecord::Base.connection.clear_query_cache

之后再执行User.all即可看到更新后的值。

2. 强制重新查询

使用reload方法强制跳过缓存,从数据库获取最新数据:

User.all.reload

3. 重新查询单个用户

如果只需验证目标用户的最新值,直接重新查询该用户即可:

User.find(1).posts_counter

注:你的代码逻辑本身没有问题,after_save回调配合increment!的写法是正确的,increment!会自动持久化修改到数据库,无需额外调用save。

内容的提问来源于stack exchange,提问作者andres g

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 01:25:24