Mongoidのcallbackの実行順序

以下のgistが超わかりやすかった。リンク先のコメント欄にはMongoid 5.0.1の場合も追記されている。

https://gist.github.com/jingoro/3015664#gistcomment-1629159

require 'rubygems'
require 'bundler/setup'
require 'mongoid'
Mongoid.configure do |config|
config.master = Mongo::Connection.new('localhost', 27017, :logger => nil).db('mongoid-test')
end
class A
include Mongoid::Document
field :a
before_save { p 'before_save' }
before_update { p 'before_update' }
before_create { p 'before_create' }
after_save { p 'after_save' }
after_update { p 'after_update' }
after_create { p 'after_create' }
around_save { |&b| p 'start around_save'; b.call; p 'end around_save' }
around_create { |&b| p 'start around_create'; b.call; p 'end around_create' }
around_update { |&b| p 'start around_update'; b.call; p 'end around_update' }
end
a = A.new
a.save
#=> "before_save"
#=> "start around_save"
#=> "before_create"
#=> "start around_create"
#=> "end around_create"
#=> "after_create"
#=> "end around_save"
#=> "after_save"
a.a = 1
a.save
#=> "before_save"
#=> "start around_save"
#=> "before_update"
#=> "start around_update"
#=> "end around_update"
#=> "after_update"
#=> "end around_save"
#=> "after_save"

Mongoidのany_ofがorではなくandになる

any_ofでorの結果を取得したいのに、結果はandになってしまう、という場合

User.any_of(:created_at.gte => 1.week.ago, :name => /^j/)

上記のコードは、1つのハッシュをany_ofとして渡している。any_ofはハッシュを複数渡すのが正解なので、以下のコードが正しい。

User.any_of({:created_at.gte => 1.week.ago}, {:name => /^j/})

よくミスするのでメモ。

Mongoidでcallback(before_save等)を呼ばずにupdateする

before_save, after_saveといったコールバックを実行せずにフィールドの値を更新するには、setメソッドを利用する。after_saveの中で値を更新したい時に便利。
以下は例。

item = Item.first
item.set(:description, "It's so nice!")

簡単ですね。

http://mongoid.org/en/mongoid/docs/persistence.html#atomic

Mongooseでフィールドのデフォルト値を現在時刻にする

公式ドキュメントのdefaultsのページに書いてあった。

以下のように書けばドキュメント作成時のデフォルト値を現在時刻に指定できる。

new Schema({
	date: { type: Date, default: Date.now }
})

次のように書いていて、データベースに追加するたびに同じ時刻が書き込まれるので不思議に思っていた。

new Schema({
	date: { type: Date, default: Date.now() }
})
// あるいは
new Schema({
	date: { type: Date, default: (new Date()).getTime() }
})

上記のように書いてしまうと、スキーマを作成した時刻が毎回書き込まれてしまう。defaultには、値も渡せるし、関数も渡せるということをよく理解していなかったためにミスした。

node.jsでMongoDBの接続に失敗する時

node.js, Express, MongoDBという組み合わせを、Ubuntu12.04のVM上で動かしていたら、Webアプリケーションを起動(npm start)した時に以下のようなエラーが出るようになってしまった。

[Error: failed to connect to [localhost:27017]]

以下2つの記事を参考にして解決。

続きを読む node.jsでMongoDBの接続に失敗する時