使用Redis进行Rails验证

时间:2011-12-20 06:22:46

标签: ruby-on-rails ruby-on-rails-3 activerecord redis

我有一堆Redis getter和setters,比如

def share_points= p
  $redis.set("store:#{self.id}:points:share", p) if valid?
end

问题是,ActiveRecord的验证不会阻止值插入redis。如何在不在每个setter上添加if valid?的情况下执行此操作? valid?每次调用时都会计算验证。

2 个答案:

答案 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

我认为即使这可以重构和清理,但你明白了。