ActiveRecord
まずは基本的なバリデーションやコールバックを押さえておけばActiveRecordのモデルを使いこなせる。
ActiveRecordによるモデルには大きく分けて3つの側面がある。
-
モデルクラスに記述しなくともテーブルのカラムがプロパティにセットされる。 1つはDBと接続し、DBのレコードとActiveRecordオブジェクトを結びつけるという役割。 モデルクラスの実装に何も記述しなくても、テーブルのカラム情報を取得しモデルのフィールド情報に自動で反映する機能
-
SQLの構築を抽象化する機能やコネクションプール、接続情報を隠蔽する機能を提供する。
-
ビジネスロジックの実装的な振る舞いに関するところ、すなわちバリデーションやレコード保存時などに実行するさまざ まなコールバックなどを実行する役割。
Active record モデル命名規則
Active record モデル関連 コマンド
※/db/migrate/ 以下にマイグレーションファイルが作成されるので、NOT NULLだったり、カラム名の修正とかをしたい場合は、ここで直接修正してしまう。
# マイグレーションファイル作成コマンド
$ rails generate migration クラス名
# モデル作成
$ rails generate model モデル名
# テーブルを作成する
$ rails g model モデル名 フィールド:型:(unique|index) 以降必要なだけ
$ rails g model User uuid:string:unique name:string
マイグレーション実行&ロールバック&確認
# 実行
$ rake db:migrate
# ロールバック
$ rake db:rollback
# 確認
$ rake db:migrate:status
Status Migration ID Migration Name
--------------------------------------------------
up 20140909055128 Create users
up 20140909055234 Create spots
up 20140909055735 Create user spots
up 20140909072813 Change options to user spot
直接SQLを使わずにDBのテーブルやカラムなどの構造を変更できる仕組み
def change
end
# 昔からある記法
def up
def down
has_many
has_manyは関連づけの中でも参照される側(親側)。一多対の関連
where
whereメソッドに カラム名:配列
というハッシュを渡すと、カラムの値が複数の候補のどれかと同じ
members = Member.where(number: [15, 17, 19]) # 15 or 17 or 19
members = Member.where(number: 12..14) # 12 ~ 14
members = Member.where.not(number: 12..14) # 12 ~ 14ではない
members = Member.where.("name = ?", name) # プレースホルダ
Railsのモデル(ActiveRecord) クラスのクラスメソッドについて
Railsのモデル(ActiveRecord)はDBからデータを取り出したり検索したりするための強力な機能を備えている
以下はモデルクラスのクラスメソッド欄 Railsのモデル群はActiveRecord::を継承していることを忘れてはいけない。
idsメソッド
member = Member.ids
→ [0, 1, 2] # SELECT "members"."id" FROM "members"
テーブルに存在するすべてのレコードの主キーを配列として取得ができる
find 1件
主キーの値を指定し一件取得したい場合に使用する。 例外が発生することを前提にしたプログラムとして作成する
member = Member.find(3)
- 例外 ActiveRecord::RecordNotFoundが発生する
find_by 1件
検索対象のカラムはいくつも設定し1件取得したい場合
あるカラムを使ってレコードを検索し、最初に一致したものを返す
引数には name: "Taro"
のようにハッシュでカラム名: 値を指定する。
member = Member.find_by(sex: 1, administrator: false)
- 例外 例外は発生せずnilが返る
where
複数のレコードを検索する
-
戻り値 ActiveRecord:Relationというクラスのインスタンスで検索結果のレコードを保持した配列風オブジェクト
-
例外 例外は発生せず、空のActiveRecord::Relationインスタンスが返る
to_a
即座に明治的に任意の箇所でSQLを発行したい場合。
ActiveRecord::Relation
配列と同様のアクセスのためのインターフェースを持っている。このインターフェースを利用することでSQLの実行結果のデータを普通の配列 と同じような感覚で扱える。
ActiveRecordのQuery Interfaceによる操作結果をオブジェクトとして表現したもの
SQLのそれぞれの表現に対応したメソッドをチェインさせることが可能。 これらのインターフェースをQuery Interfaceと呼ぶ
- メソッド実行について
インタプリターだと、コンパイルしながら実行していくを前提に考える メソッド(チェインを含む)呼び出しを通じてActiveRecord:Relationは内部でどのようなSQLを発行するかという情報だけを保持する。 そのため実際にそのSQL実行結果が必要になるまではDBに対するアクセスは発生しない。
- ActiveRecord::Relationメソッド保持の仕組み
- ActiveRecord::Relationに対してQuery Interfaceが呼ばれるとActiveRecord::Relationのインスタンスが生成される
- ActiveRecord::Relationに対して繰り返しQuery Interfaceを呼び出すことができる
- 繰り返し呼び出したQuery InterfaceはActiveRecord::Relationのインスタンスに蓄積されどんなSQLを発行するかの情報が更新される
- 実際にデータが必要になった時点で、蓄積された情報をもとにSQLを発行しデータを取得する。
このように設計されている理由はメソッドいチェインによるクエリの構築を行うため。 検索メソッドを実行した途端、即座にSQLが実行されてしまう設計の場合最初のメソッド呼び出しの時点ですべての条件を準備して一度にメソッドへ渡す必要が出てきてしまうため出てきてしまうため。