2011-12-20 13 views
2

と私はRailsのバリデーションはRedisの

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

事があるようなRedisのゲッターとセッターの束を持っている、から値を停止しないのActiveRecordの検証はRedisのに挿入されています。すべてのセッターにif valid?を追加せずにこれを行うにはどうすればいいですか? valid?は、呼び出されるたびに検証を計算します。

答えて

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 

は、私もこれはリファクタリングとクリーンアップすることができると思うが、あなたのアイデアを得ます。

+0

ありがとうございます。それは私が今日思いついた解決策ですが、若干の変更が加えられました。マルチを1つずつ行うよりも速いのですか? – CamelCamelCamel

+1

あなたはまだそれを一つずつ実行していますが、 'multi'はクライアントが要求をパイプライン化してトランザクションの一部として行うことを可能にします。 –

1

編集しているモデルがactive_recordから派生している場合は、検証を行うredisの特定のラップされた呼び出しが必要です。例えば

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から派生していない場合:ベース、あなたはここで説明したようActiveModelを使用して、よりAR ::ベースのような構造を思い付くすることがあります:http://purevirtual.de/2010/04/url-shortener-with-redis-and-rails3/

+0

ああ、あなたがすることができるもう一つのことは、$ redis.setのエイリアシングですが、$ redis.setへのすべての呼び出しに影響するため、適切ではないかもしれません –

+0

私はMongoDBを使用しています(マングイード)と同じモデルのレディスと一緒に。有効な使用の問題?それが呼び出されるたびにすべてのモデルバリデーションが実行されるということです(ソースコード:https://github.com/rails/rails/blob/master/activemodel/lib/active_model/validations.rb)。 4つのredisプロパティを更新すると、検証が5回実行されます。 – CamelCamelCamel

+0

検証にコストがかからない場合は重要ですか? –

関連する問題