ARを読んでみる3

require 'rubygems'
require_gem 'activerecord'
 
ActiveRecord::Base.establish_connection(
   :adapter => 'mysql',
   :host => 'localhost',
   :username => 'ypuser_d',
   :password => 'ror',
   :database => 'yellowpage_development'
)

class Item < ActiveRecord::Base
end

Item.count

こんな感じで使うcountメソッド
定義されてるのはcalculations.rb
ActiveRecord::Calculations::ClassMethodsモジュールのメソッドなんだ!
実行時にActiveRecord::Baseのクラスメソッドになるぞ!


※Rails 1.1.6
※activerecord-1.14.4

countメソッド

countメソッドには引数は2つまでだ!
associationを使わない場合、calculateメソッドを呼ぶ
引数・・・operationは:count、column_nameは:all、optionsは空ハッシュ
calculateメソッドからの戻り値を返す。associationを使う場合はcount_with_associationsメソッドを呼ぶ。

calculateメソッド

validate_calculation_optionsメソッドを呼ぶ
初回はnilが帰ってくる
なんだこれ?
意義がわからず


引数column_nameが:allのとき、column_nameに'*'をセット


メソッドcolumn_forをcolumn_nameを引数にして呼ぶ
戻り値はcolumnにセット


メソッドselect_aggregateを引数operation, column_name, optionsで呼ぶ
戻り値はSQLのSELECT句の中身の文字列
aggregateにセット


メソッドcolumn_alias_forを引数operation, column_nameで呼ぶ
"count *"
"count all"
"count_all"
戻り値はソースコードに書いてあるドキュメントのような感じ(おぃ
aggregate_aliasにセット


optionsにキー:groupsがない場合
メソッドexecute_simple_calculationを引数operation, column_name, column, aggregate, aggregate_alias, optionsで呼ぶ
戻り値は
この戻り値がcalculateメソッドの戻り値
execute_simple_calculationはパラメータをconstruct_calculation_sqlに渡す。
construct_calculation_sqlメソッドはSQL文を返す。
このSQL文をconnecton.select_valueに渡して、SQLの結果を得るんだ
select_valueメソッドはactive_record/connection_adapters/abstract/database_statements.rbで定義されてる。
ActiveRecord::ConnectionAdapters::DatabaseStatementsモジュールのselect_valueメソッドは
ActiveRecord::ConnectionAdapters::AbstractAdapterにmixinされてる


select_value

(connection_adapters/mysql_adapter.rbの)select_one

select

execute

(active_record/vendor/mysql.rbの)query

さらに深い・・・
とっても遠いよ!!


type_cast_calculated_valueメソッドでSQLの結果(文字列)を型変換だ
opertionが'count'だったら結果をIntegerに変換するぞ
opertionが'avg'だったら結果をFloatに変換するぞ
opertionがそれ以外だったらtype_castメソッドで変換するぞ
type_castメソッドはconnection_adapters/abstract/schema_definitions.rbで定義されているんだ

validate_calculation_optionsメソッド(private)

ActiveSupportのHash拡張メソッドassert_valid_keysを呼ぶ
引数は定数CALCULATIONS_OPTIONS + ":include"
assert_valid_keysメソッド

def assert_valid_keys(*valid_keys)
  unknown_keys = keys - [valid_keys].flatten
  raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
end

keysがどこで定義されてるかわからんバイ。。
いきなり現れるクラス変数??