スキーマレスなMongoDBでmethod_missingを避ける
MongoDBです。ORMにMongoidです。
ご存知の通り、スキーマレスなわけですよ。スキーマレスということはあれですよ、ドキュメントによってフィールドがあったりなかったりしちゃうわけです。
通常、Modelの各フィールドに対してはMongoidがうまいことやってくれるアクセサをとおしてやりとりします。
class Person include Mongoid::Document field :name, type: String end
上記のようなドキュメントのフィールドに対して、次のようにアクセスできちゃうのです
person.name
ところが、例えばfirst_nameがnilの場合、メソッドチェーンなんかしてしまうとmethod_missingとなることがあります。
アプリ側で例外処理をしてもいいのですが、DB側でうまいことやってほしい場合もあります。
そんなとき、Mongoidならこんな手があります。
If the attribute does not already exist on the document, Mongoid will not provide you with the getters and setters and will enforce normal method_missing behavior. In this case you must use the other provided accessor methods: ( and =) or (read_attribute and write_attribute).
# Raise a NoMethodError if value isn't set. person.gender person.gender = "Male" # Retrieve a dynamic field safely. person[:gender] person.read_attribute(:gender) # Write a dynamic field safely. person[:gender] = "Male" person.write_attribute(:gender, "Male")http://mongoid.org/docs/documents/dynamic.html
[] あるいは read_attribute、write_attribute を使うことで、method_missingを避けられます。