首先,counter_culture 似乎是增强rails 的counter_cache 功能的一种方式...
用于缓存关联上所属对象的数量。例如,Post 类中的 comments_count 列包含许多 Comment 实例,将缓存每个帖子的现有 cmets 数。
从你的问题来看,它可能不是正是你想要的。
好的,我明白了。您在 User 模型中使用 points 来创建可用于更广泛的应用程序功能的“缓存”列。好的,这很酷...
--
然后,您的设置将看起来像 (您手动设置了 counter_cache 列,现在 gem 处理它):
#app/models/user.rb
class User < ActiveRecord::Base
counter_cache :points
end
#app/models/point.rb
class Point < ActiveRecord::Base
belongs_to :user, counter_cache: true
end
那么问题是,当您更新 points 模型时,您需要能够更新 users 模型中的“缓存”列,现在无需任何回调.
什么是正确的 ActiveRecord 回调而不是 before_save
我假设您在 User 模型上调用 before_save(IE 添加相关数据并放置 points 列?
如果是这样,您应该尝试在 Point 模型上使用回调,可能是这样的:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :points
end
#app/models/point.rb
class Point < ActiveRecord::Base
belongs_to :user, inverse_of: :points
after_commit :update_user
private
def update_user
if user?
user.update(points: x + y + z)
end
end
end
--
观察员
如果您有真正的问题,可以查看ActiveRecord observers。
这是我写的一个答案:Ruby On Rails Updating Heroku Dynamic Routes
这是否会在没有任何回调的情况下触发是另一回事,但我可以说的是,它可以为您提供您可能无法访问的功能:
#config/application.rb (can be placed into dev or prod files if required)
config.active_record.observers = :point_observer
#app/models/point_observer.rb
class PointObserver < ActiveRecord::Observer
def before_save(point)
#logic here
end
end
测试它的一个好方法是使用不同的方法(您必须使用rails-observers gem)。即:
#app/models/point_observer.rb
class PointObserver < ActiveRecord::Observer
def initialize(point)
#if this fires, happy days
end
end