find、find_by、whereの違い

しっかりと、`どう違う`という説明ができなかったので、まとめました。

## findメソッドとは
各モデルの`id`を検索キーとしてデータを取得するメソッド
id以外の条件で`検索不可`
取得したいデータのidの値が、1、10と`具体的に分かっている場合`に使用する。

(例)Aiueoモデルからid=1のデータを取得したい場合

```
irb(main):001:0> Aiueo.find(1)

  Aiueo Load (0.9ms)  SELECT  "aiueos".* FROM "aiueos" WHERE "aiueos"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
=> #<Aiueo id: 1, name: "名前0", title: "タイトル0", created_at: "2018-03-13 04:39:22", updated_at: "2018-03-13 04:39:22">
```

該当データがない場合は、`ActiveRecord::RecordNotFound`が返ってくる。
つまり、`エラー`が返ってくるということ。

```
irb(main):006:0> Aiueo.find(1000000)
  Aiueo Load (0.4ms)  SELECT  "aiueos".* FROM "aiueos" WHERE "aiueos"."id" = $1 LIMIT $2  [["id", 1000000], ["LIMIT", 1]]
ActiveRecord::RecordNotFound: Couldn't find Aiueo with 'id'=1000000

```

## find_byメソッドとは
各モデルを`id以外の条件で`検索するメソッド(idでも検索可能)
複数の検索条件を指定可能
返ってくる結果は、最初にヒットした`1件のみ`
`id及びid以外の条件が分かっている場合`、その条件に該当する最初のデータを取得したい場合に使用する。

(例)Aiueoモデルからタイトルが「タイトル0」のデータを取得する場合

```
irb(main):004:0> Aiueo.find_by(title: "タイトル0")
  Aiueo Load (0.4ms)  SELECT  "aiueos".* FROM "aiueos" WHERE "aiueos"."title" = $1 LIMIT $2  [["title", "タイトル0"], ["LIMIT", 1]]
=> #<Aiueo id: 1, name: "名前0", title: "タイトル0", created_at: "2018-03-13 04:39:22", updated_at: "2018-03-13 04:39:22">
```

該当データがない場合は、`nil`が返ってくる。

```
irb(main):007:0> Aiueo.find_by(title: "タイトル")
  Aiueo Load (0.6ms)  SELECT  "aiueos".* FROM "aiueos" WHERE "aiueos"."title" = $1 LIMIT $2  [["title", "タイトル"], ["LIMIT", 1]]
=> nil
```

## whereメソッド
各モデルを`id以外の条件で`検索する場合
該当するデータ全てが返ってくる。

(例)Aiueoモデルからタイトルが「タイトル0」のデータを取得する場合

```
irb(main):005:0> Aiueo.where(title: "タイトル0")
  Aiueo Load (1.0ms)  SELECT  "aiueos".* FROM "aiueos" WHERE "aiueos"."title" = $1 LIMIT $2  [["title", "タイトル0"], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Aiueo id: 1, name: "名前0", title: "タイトル0", created_at: "2018-03-13 04:39:22", updated_at: "2018-03-13 04:39:22">]>
```

find_byの結果と違い、先頭に`ActiveRecord::Relation`の文字が。
ActiveRecord::Relation は、`検索クエリを組み立てるもの`で、`検索結果のオブジェクト`とは異なるものである、とのこと。

う〜ん、むずかしい・・・

`find`、`find_by`メソッドは、`検索結果のインスタンス（オブジェクト）`（簡単にいうと、検索結果のデータがつまったもの）を返すが、
`where`メソッドは、検索結果をオブジェクトとして返しているのではなく、`検索するためのプログラムを発生させ、結果を表示しているだけ`の状態（うまく説明できない・・・）

なので、whereでは、取得したデータから特定カラムのデータを取得しようとするとエラーになる。

```
irb(main):012:0> @aiueo = Aiueo.where(title: "タイトル0")
  Aiueo Load (0.6ms)  SELECT  "aiueos".* FROM "aiueos" WHERE "aiueos"."title" = $1 LIMIT $2  [["title", "タイトル0"], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Aiueo id: 1, name: "名前0", title: "タイトル0", created_at: "2018-03-13 04:39:22", updated_at: "2018-03-13 04:39:22">]>

irb(main):013:0> @aiueo.title
NoMethodError:   Aiueo Load (0.4ms)  SELECT  "aiueos".* FROM "aiueos" WHERE "aiueos"."title" = $1 LIMIT $2  [["title", "タイトル0"], ["LIMIT", 11]]
undefined method `title' for #<Aiueo::ActiveRecord_Relation:0x007fef48b8c3a8>
```
一方、find_byでは、実行結果のインスタンスが返ってきているので、特定カラムのデータも取得できる。

```
irb(main):014:0> @aiueo = Aiueo.find_by(title: "タイトル0")
  Aiueo Load (0.9ms)  SELECT  "aiueos".* FROM "aiueos" WHERE "aiueos"."title" = $1 LIMIT $2  [["title", "タイトル0"], ["LIMIT", 1]]
=> #<Aiueo id: 1, name: "名前0", title: "タイトル0", created_at: "2018-03-13 04:39:22", updated_at: "2018-03-13 04:39:22">

irb(main):015:0> @aiueo.title
=> "タイトル0"
```

## まとめ
使用区分としては、

idの値が分かっていて、そのidのデータを取得したい場合・・・find
idの値が不明で、id以外のカラムを検索条件としたい場合・・・find_by
id以外のカラムの検索条件で、複数の実行結果を取得したい場合・・・where

こんなところかなと。