ルビーfor Railsの思考のmethodを読むmissing
3384 ワード
Rubyのメソッドの検索順序は、このクラス=>このクラスincludeのモジュール=>親=>親クラスincludeのモジュールです...
最終的にこの方法が見つからない場合、組み込まれたmethod_がトリガーされます.missingメソッドの実行
デフォルトのmethod_missingは異常をトリガーし、override method_を通過することができます.missingメソッドはいくつかの特性を提供します
例えばRailsのActiveRecord、User.find_by_name()このメソッドはもともとUserクラスで定義されていませんが、override method_missingはデータベースfieldsに一致する
次にclass_を使用しますevalとsendのクエリーメソッドの動的作成と呼び出し
C:rubylibrubygems1.8gemsactiverecord-1.15.3libactive_record\base.rbのコードの一部がクリアされました.
最終的にこの方法が見つからない場合、組み込まれたmethod_がトリガーされます.missingメソッドの実行
デフォルトのmethod_missingは異常をトリガーし、override method_を通過することができます.missingメソッドはいくつかの特性を提供します
例えばRailsのActiveRecord、User.find_by_name()このメソッドはもともとUserクラスで定義されていませんが、override method_missingはデータベースfieldsに一致する
次にclass_を使用しますevalとsendのクエリーメソッドの動的作成と呼び出し
C:rubylibrubygems1.8gemsactiverecord-1.15.3libactive_record\base.rbのコードの一部がクリアされました.
# Enables dynamic finders like find_by_user_name(user_name) and find_by_user_name_and_password(user_name, password) that are turned into
# find(:first, :conditions => ["user_name = ?", user_name]) and find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password])
# respectively. Also works for find(:all), but using find_all_by_amount(50) that are turned into find(:all, :conditions => ["amount = ?", 50]).
#
# It's even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount
# is actually find_all_by_amount(amount, options).
def method_missing(method_id, *arguments)
if match = /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(method_id.to_s)
finder, deprecated_finder = determine_finder(match), determine_deprecated_finder(match)
attribute_names = extract_attribute_names_from_match(match)
super unless all_attributes_exists?(attribute_names)
attributes = construct_attributes_from_arguments(attribute_names, arguments)
case extra_options = arguments[attribute_names.size]
when nil
options = { :conditions => attributes }
set_readonly_option!(options)
ActiveSupport::Deprecation.silence { send(finder, options) }
when Hash
finder_options = extra_options.merge(:conditions => attributes)
validate_find_options(finder_options)
set_readonly_option!(finder_options)
if extra_options[:conditions]
with_scope(:find => { :conditions => extra_options[:conditions] }) do
ActiveSupport::Deprecation.silence { send(finder, finder_options) }
end
else
ActiveSupport::Deprecation.silence { send(finder, finder_options) }
end
else
ActiveSupport::Deprecation.silence do
send(deprecated_finder, sanitize_sql(attributes), *arguments[attribute_names.length..-1])
end
end
elsif match = /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/.match(method_id.to_s)
instantiator = determine_instantiator(match)
attribute_names = extract_attribute_names_from_match(match)
super unless all_attributes_exists?(attribute_names)
attributes = construct_attributes_from_arguments(attribute_names, arguments)
options = { :conditions => attributes }
set_readonly_option!(options)
find_initial(options) || send(instantiator, attributes)
else
super
end
end