【Active Record】Ruby on RailsのActive Recordを理解しよう！

## はじめに
こんにちは！

今年もこの時期がやってきましたね！
そうクリスマスシーズンならぬQiitaのアドベントカレンダーシーズンです。

ということでからくり株式会社の[アドベントカレンダー](https://qiita.com/advent-calendar/2019/caraquri)の１日目は私@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がないと

```ruby
require 'sqlite3'

SQL=<<EOS
SELECT id FROM users WHERE id = 1
EOS

db = SQLite3::Database.new('test.db')
db.execute(SQL)
```

上記のような長い一文をかかなければなりません。

上記のコードは下の1文と一緒

```ruby
User.find(1)
```

とても少なく書けます。

メソッドを宣言して、newで新しいオブジェクトを作成して、実行…。
保守性も低くなってくるし、効率も悪い。

Active Recordはこのような問題を解決してくれます。


## Active RecordはO/Rマッパー
上記のような可読性の悪いコードを書かないためにO/Rマッパーという仕組みが考えられました。

O/Rマッピングフレームワークで作られたRuby専用のO/RマッパーがActive Recordなのです。

[O/Rマッパーとは](https://qiita.com/yk-nakamura/items/acd071f16cda844579b9)

またActive Recordを使うその他のメリットとして
- よくあるSQL文はActive Recordが提供してくれるため無駄なコードを書かなくて良い
- オブジェクト指向でデータ操作を行える（O/Rマッパーを使わないとメソッドの羅列になってしまう可能性あり）
- 素のsql文でレコードをあつかうとデータが存在しない時にnilを返す=例外処理がない
といったものが挙げられます。

## Active Recordの利点①　マイグレーション
データベースは独立したアプリケーションなため、Github等でバージョン管理ができません。

昔はテーブル変更したら、sql分実行した情報をメーリスなどで共有していた（らしいです…）。

上記のやり方だと、適用漏れなどがおきる可能性があります。

データベース定義を変更したときはマイグレーションの仕組みを利用すれば、DB管理が楽になります。


```ruby
bin/rails db:migrate
```

## Active Recordのメリット② DBアクセスでの簡潔なコード

ちなみにActive Recordを使わないでDBアクセスを定義しようとすると結構な量のコードを書く必要があります。

```ruby

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だと

```ruby

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ライフが素晴らしいものになることでしょう。


参考元
[X-HACK 勉強会](https://x-hack.connpass.com/)
[Rails Guides](https://railsguides.jp/)