これは何?

RailsガイドのActive Recordの基礎が理解をする上で非常によかったので、

振り返れるようにまとめます。


Active Recordって何?

MVCのM、つまりモデルに相当するもので、Active Recordを介してデータベースとやりとりができます。

なお、データベースとやりとりをする時の考え方として、ORM(オブジェクトリレーショナルマッピング)を採用しており、

モデルをインスタンス化したオブジェクトと、MySQLのようなRDBを接続することで様々なことを直接SQL文を書かずに実現しています。


Active Recordの機能


  • モデルおよびモデル内のデータを表現する

  • モデル間の関連付け(アソシエーション)を表現する

  • 関連するモデルを介した継承階層を表現する

  • データがデータベースに永続的に保存される前に検証(validation)を行なう

  • オブジェクト指向の表記方法でデータベースを操作する


覚えるべきルール


  • モデルのクラス名の複数形がDBのテーブル名


    • image.png



  • 外部キーはテーブル名の単数形_idにする


    • users, postsテーブルの外部キーはuser_id, post_id



  • 主キーは自動生成される


モデルクラスってどこまで何やってるの?

例えば、

bundle exec rails generate model User name:string email:string

でモデルクラスを作成するとします。

(その後、bundle exec rails db:migrateとかはやっておいてください)

class User < ApplicationRecord

end

上記のようなモデルクラスが作成されますが、これがどこまで何をやってるかというと、


  • Userモデルとusersテーブルの関連付け。

  • usersテーブルの各カラムをUserモデルのインスタンスの属性に関連付け。

をやっています。

そのため、上記のコードだけでもいきなり、

user = User.new(name:"test", email:"test@gmail.com")

user.name = "Jiggaman"
user.save
user1 = User.find_by(name:"Jiggaman")
user1.destroy

みたいに直接DBを触って出し入れしたりすることができてしまうのです。


バリデーション

モデルではDBに保存される前にValidationをかけることができます。

基本的には、インスタンスを生成するコントローラーにて、


  • create

  • save

  • update

がされる前にモデルに定義されているValidationを通り、有効な場合のみにDBに保存されるという流れとなります。

なお、Validationを通らずにスキップしてしまうメソッドもあるため、全てがValidationを通ると思わないように注意してください。

saveをするタイミングでValidationエラーとなると、

errors.messagesを返します。

そのため、下記のように設定することが可能となります。


models/user.rb

class User < ApplicationRecord

validates :name, presence: true
end


controllers/users_controller.rb

def create

user = User.new
if user.save
# DBに保存成功
else
# DBに保存失敗
user.errors.full_messages.each do |error|
puts error
end
end
end

今回の場合、nameカラムが空欄のままDBに保存しようとしているため、validationにかかってerrorとなります。

なお、:messageオプションを使用することで、バリデーション失敗時のエラーメッセージをカスタマイズすることができます。

validates :name, presence: { message: "must be given" }


バリデーションヘルパー

こちらから下記のヘルパーそれぞれの説明を確認可能です。


  • acceptance

  • validates_associated

  • confirmation

  • exclusion

  • format

  • inclusion

  • length

  • numericality

  • presence

  • absence

  • uniqueness

  • validates_with

  • validates_each


コールバック

ValidatesがDBに保存する直前に動作するものだったのに対し、

コールバックは、オブジェクトの状態が切り替わる「前」or「後」で動作します。

オブジェクトの状態が切り替わるタイミングとは、

オブジェクトが作成/保存/更新/削除/検証/DBからの読み込みなどです。

下記が基礎的なコールバックです。


models/user.rb

class User < ApplicationRecord

# createメソッドのタイミングだけ事前にnormalize_nameメソッドが走ります
before_validation :normalize_name, on: :create
# create, update両方のタイミングで事後にset_locationメソッドが走ります
after_validation :set_location, on: [ :create, :update ]
# 下記のように事前に呼び出すメソッドの内容をブロックで表現することも可能です
before_create do
self.name = login.capitalize if name.blank?
end

# コールバックメソッドはprivateで宣言してください
private
def normalize_name
self.name = name.downcase.titleize
end

def set_location
self.location = LocationService.query(self)
end
end


もう少し詳細な利用可能なコールバックと順番はこちらを参照してください。


アソシエーション

モデルとモデルを関連づけることによって、はるかに簡単な操作で実現したいことができるようになりますので是非知っておいてください。

効果を実感できない方は、こちらの例を見ることでそのバグツンの効果を実感できると思います。