我有一堆Redis getter和setters,比如
def share_points= p
$redis.set("store:#{self.id}:points:share", p) if valid?
end
问题是,ActiveRecord的验证不会阻止值插入redis。如何在不在每个setter上添加if valid?
的情况下执行此操作? valid?
每次调用时都会计算验证。
答案 0 :(得分:1)
如果您正在编辑的模型是从active_record派生的,那么您可能希望对redis进行特定的包装调用,以便为您进行验证。 e.g。
class Foo < ActiveRecord::Base
def rset(key,value)
$redis.set("store:#{self.id}:key", value) if valid?
end
def share_points=(p)
rset("points:share", p)
end
end
你也可以把它放在一个模块中并包含它。
如果您没有从AR:Base派生,您可能希望使用ActiveModel提供更多类似AR :: Base的结构,如下所述:http://purevirtual.de/2010/04/url-shortener-with-redis-and-rails3/
答案 1 :(得分:1)
如何切换到after_save
回调方法,在该方法中存储已更改的所有字段,并将其全部保留一次以进行重新设置。
类似的东西:
class Foo < ActiveRecord::Base
after_save :persist_to_redis
attr_accessor :redis_attributes
def share_points=(p)
@redis_attributes ||= {}
@redis_attributes[:share_points] = p
end
def something_else=(p)
@redis_attributes ||= {}
@redis_attributes[:something_else] = p
end
private
def redis_store_share_points(value)
$redis.set("store:#{self.id}:key", value)
end
def redis_store_something_else(value)
$redis.set("something_else:#{self.id}", value)
end
def persist_to_redis
$redis.multi do
@redis_attributes.each_pair do |key, value|
send("redis_store_#{key}".to_sym, value)
end
end
end
end
我认为即使这可以重构和清理,但你明白了。