動的属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| require 'activerecord'
ActiveRecord::Base.establish_connection :adapter => "sqlite3",
:database => "dbfile"
ActiveRecord::Base.connection.create_table :tasks do |t|
t.string :description
t.boolean :completed
end
class Task < ActiveRecord::Base; end
task = Task.new
task.description = 'ブログの記事作成'
task.completed = true
task.save
task.description # => "ブログの記事作成"
task.completed? #=> true
|
上記のコードに属性にアクセスする4つのメソッドを呼び出している。(description=()、completed=()、description()、completed?())
しかし、これらの「属性アクセサ」はTaskクラスの定義にはない。
では、このアクセサはどこからきたものなんだろうか。
ActiveRecord::Base#method_missing()
実際にactive_record/attribute_methods.rb
ではActiveModel::AttributeMethods
をinclude
してmethod_missing()
を使っている。method_missing()
が呼び出されたら該当メソッドがあるかどうかを判断し、ゴーストメソッドを生成する。そのゴーストメソッドはゴーストアクセサになり、動的に属性にアクセスすることができる。
動的ファインダ
1
2
3
4
5
6
7
8
9
10
| task = Task.find(:first, :conditions => {:completed => true})
task.description # => "ブログの記事作成"
task = Task.find_by_description('ブログの記事作成')
task.id # => 1
Task.find_all_by_completed(true)
Task.find_by_description_and_completed('ブログの記事作成', true)
Task.find_or_create_by_description('ランチターイム')
Task.find_by_description!('帰宅')
|
ActiveRecord::Base.find
はfind_by_<attr>
のように属性名を含むメソッドでの検索もできる。
and, or での連結などもできる。
これも動的属性と同じく「ゴーストメソッド」で実装している。
ここでもやはり最初にmethod_missing
でメソッドを定義して次からは直接呼び出せるようにしている。
参照
rails/activerecord at master · rails/rails · GitHub