はじめに
こんにちは!
今年もこの時期がやってきましたね!
そうクリスマスシーズンならぬQiitaのアドベントカレンダーシーズンです。
ということでからくり株式会社のアドベントカレンダーの1日目は私@nakasan_comが担当します。
よろしくお願いします。
今回はRuby on RailsのActive Recordについて取り上げようと思います。
Active Recordが理解できればRailsの8割は理解したも同然?
お手柔らかにお願いします。
そもそもウェブアプリケーションとは?
Active Recordについてお話しする前に、そもそもWebアプリケーションとは何でしょうか?
Railsは主としてWebアプリケーションの構築を得意としています。
結論としてWebアプリとは(誤解を恐れずにいえば)ブラウザ上で動くDBと連携したシステムのことです。
厳密にはDBと連携しないものもあるが、大多数がDBと連携しています。
そのため、データベースの操作がWebアプリケーションの基礎となっているのです。
DBとの連携ができなければ何もできない。
わざわざActive Recordを使う理由
そこでRailsはActive Recordというgemを導入しているのです。
わざわざsql文を書くのは面倒くさい…。
id=1のユーザーを取得したい場合、Active Recordがないと
require 'sqlite3'
SQL=<<EOS
SELECT id FROM users WHERE id = 1
EOS
db = SQLite3::Database.new('test.db')
db.execute(SQL)
上記のような長い一文をかかなければなりません。
上記のコードは下の1文と一緒
User.find(1)
とても少なく書けます。
メソッドを宣言して、newで新しいオブジェクトを作成して、実行…。
保守性も低くなってくるし、効率も悪い。
Active Recordはこのような問題を解決してくれます。
Active RecordはO/Rマッパー
上記のような可読性の悪いコードを書かないためにO/Rマッパーという仕組みが考えられました。
O/Rマッピングフレームワークで作られたRuby専用のO/RマッパーがActive Recordなのです。
またActive Recordを使うその他のメリットとして
- よくあるSQL文はActive Recordが提供してくれるため無駄なコードを書かなくて良い
- オブジェクト指向でデータ操作を行える(O/Rマッパーを使わないとメソッドの羅列になってしまう可能性あり)
- 素のsql文でレコードをあつかうとデータが存在しない時にnilを返す=例外処理がない
といったものが挙げられます。
Active Recordの利点① マイグレーション
データベースは独立したアプリケーションなため、Github等でバージョン管理ができません。
昔はテーブル変更したら、sql分実行した情報をメーリスなどで共有していた(らしいです…)。
上記のやり方だと、適用漏れなどがおきる可能性があります。
データベース定義を変更したときはマイグレーションの仕組みを利用すれば、DB管理が楽になります。
bin/rails db:migrate
Active Recordのメリット② DBアクセスでの簡潔なコード
ちなみにActive Recordを使わないでDBアクセスを定義しようとすると結構な量のコードを書く必要があります。
require 'sqlite3'
class User
attr_accessor :id, :name
@table_name = "users"
@db = SQLite3::Database.new("test.db")
@db.results_as_hash = true
def self.select_all()
sql = "select * from #{users}";
models = []
@db.execute(sql).each do |r|
model = self.new
model.id = r["id"]
model.name = r["name"]
models << model
end
models
end
def self.first()
sql = "select * from #{@table_name} limit 1";
res = @db.execute(sql)[0]
model = self.new
model.id = res["id"]
model.name = res["name"]
model
end
def self.where_name(name)
sql = "select * from #{@table_name} where name = '#{name}'";
res = @db.execute(sql)
models = []
res.each do |r|
model = self.new
model.id = r["id"]
model.name = r["name"]
models << model
end
models
end
end
上記のコードはusersというテーブルに対して全てのレコードを取得する、最初の1件を取得する、名前(name)で検索するというメソッドを提供しています。
Active Recordだと
require "active_record"
require 'sqlite3'
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'test.db')
class User < ActiveRecord::Base
end
上記のコードを書くだけで全てのUserを取得する、Userの最初の1件を取得する、Userを検索する(find_by)を実現するメソッドが実現できてしまいます。
短い、、、。
最後に
今回は簡単ですがActive Recordについて紹介させていただきました。
DBを簡単に実現してくれるRailsもといActive Recordを使いこなせればきっとRailsライフが素晴らしいものになることでしょう。