2011-01-16 5 views
6

私はmongodbで作業するためにRailsとmongoidを使用しています。mongdbを使った簡単なブールデータ更新ですか?

通常、Active:Recordで作業する場合、レールには.toggle!メソッドにアクセスできます。単純にdbのブール値フィールドの値を反転することができます。

残念ながら、この方法は、MongoDBのため使用できません。...これは残念なことです

user = User.first 
user.toggle!(:admin) 
NoMethodError: undefined method `toggle!' for #<User:0x00000100eee700> 

と愚かに十分な、私はいくつかの複雑なコードなしで周りを取得する方法を見ていない...

どれでもどのように同じ結果を簡潔に達成するための提案?

おかげで、

アレックス

PS:また問題の一つは、私がフィールドを変更したい場合、それが再び検証を通過するということです...そしてそれがために求めています:パスワードたIドン「Tはそう、DBに保存します。

User.first.admin = !User.first.admin 

ても動作しません:(

答えて

6

をここでの問題は、MongoDBは、特にmongoidないtoggle! 0の一部であり、ですが、幸いにも複製が難しくありません。

def toggle!(field) 
    send "#{field}=", !self.send("#{field}?") 
    save :validation => false 
end 

あなたのモデルにこれを追加(またはモジュールにそれを追加し、あなたのモデルに含める)、そしてあなたのMongoidモデルは、あなたがARに慣れているものに相当する機能を得ることができます。フィールドの値を読み取って反転し、(セッターを介してtoggle!文書に従って)それを書き、検証をバイパスして文書を保存します。

+0

これは本当に素晴らしいです!正確に私が探していたもの::) sendでその構文を知らなかったのですか?私はそれが正確に何かを確認していないのですか? – Alex

+0

'send'は、オブジェクトにメソッドを送ります(" send message to ")。 '@ foo.bar(:baz)'は '@ foo.send(" bar "、:baz)'と同じです - メソッド名をsendで指定するので、変数などを渡すことができます。これはRubyのメタプログラミングで頻繁に使用されています。 –

+0

ありがとうございます。しかし、徹底的にテストした後、実際にすべての検証をバイパスするわけではありません。私はvalidates_length_of:password、:minimum => 6、:maximum => 40、toggleを使用すると、パスワードの長さにエラーが表示されます:(しかし、validates presencesなどではありません。 attr_accesibleなので、長さのバリデーション以外にはほとんど完璧です。 – Alex

0

検証が原因のタイプで動作しませんでした[OK]を、コードは次のようになります。

save :validate => false (not :validation) 
0
# Get object's boolean field and toggle it 
# @param [Object] mongoid object 
# @param [String, Symbol] flag 
# @example 
# foo = User.find('123') 
# toggle_flag!(object: foo, flag: :bar) 

def toggle_flag!(object:, flag:) 
    object.update(flag => !object[flag]) 
    object.save! 
end 
+0

コードを説明してください。 –

+0

完了!私は説明のためにヤードを使用しました。 – arkhwise

関連する問題