ActiveRecord覚書

RailsActiveRecord)のfindについて自分用の覚書。

  • 環境

ruby 1.9.3p0
Rails 3.1.3

  • モデルの作成

従業員モデルの作成

$ rails generate model employee first_name:string last_name:string birth_date:date sex:string department_id:integer hire_date:date

部門モデルの作成

$ rails generate model department name:string
  • 準備:DBの用意

Railsのmigrationを実行し下記のような構造のテーブルを作成しました。
よくあるやつですね。
(migrationによりテーブル作成しているのでcreated_at, updated_at列
も実際のテーブルには付加されています。)

$ rake db:migrate

employeesテーブル(従業員テーブル)

id ID(主キー)
first_name
last_name
birth_date 誕生日
sex 性別
department_id 部門ID
hire_date 入社日

departmentsテーブル(部門テーブル)

id ID(主キー)
name 部門名

テーブルができたら適当なデータを5件くらい各テーブルにINSERT。

  • findの確認

rails consoleコマンドによりfindの動作を確認。
◎find()メソッド

Employee.find(1)
Employee Load (14.6ms)  SELECT `employees`.* FROM `employees` WHERE `employees`.`id` = 1 LIMIT 1
=> #<Employee id: 1, first_name: "太郎", (略), updated_at: nil>

オブジェクトとして取得できました。
では見つからない場合はどうなるのだろう。

Employee.find(999)
Employee Load (0.8ms)  SELECT `employees`.* FROM `employees` WHERE `employees`.`id` = 999 LIMIT 1
ActiveRecord::RecordNotFound: Couldn't find Employee with id=999
	from /home/sun-rise/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.1.3/lib/active_record/relation/finder_methods.rb:339:in `find_one'
        ()

例外が投げられる。


◎find_by_***()メソッド

Employee.find_by_id(1)
Employee Load (0.2ms)  SELECT `employees`.* FROM `employees` WHERE `employees`.`id` = 1 LIMIT 1
=> #<Employee id: 1, first_name: "太郎", (略), updated_at: nil>

見つからない場合、

Employee.find_by_id(999)
Employee Load (0.3ms)  SELECT `employees`.* FROM `employees` WHERE `employees`.`id` = 999 LIMIT 1
=> nil

nilが返される。


◎find(:all, :conditions=>[...])メソッド

Employee.find(:all, :conditions => ['id=:id', {:id=>1}])
Employee Load (1.3ms)  SELECT `employees`.* FROM `employees` WHERE (id=1)
=> [#<Employee id: 1, first_name: "太郎", (略), updated_at: nil>]

オブジェクトが配列に格納されている。
見つからない場合、

Employee.find(:all, :conditions => ['id=:id', {:id=>999}])
Employee Load (1.0ms)  SELECT `employees`.* FROM `employees` WHERE (id=999)
=> []

空の配列が返される。


find()メソッド、find_by_***()メソッドには LIMIT 1 が付き、合致するレコードが
複数テーブルに存在していても1件分のオブジェクトが返される。