2016.5.4
2017.5.25

Active Recordの利用

Rubyをやるなら使ってみたいと思っていたO/Rマッパー系のフレームワーク。

最近はO/Rマッパーなしでは開発したくないくらい重要なものなので、これを機会に色々と試してみたいと思います。

目次

  • インストール
  • 使い方
  • 検索
  • 挿入
  • 更新
  • saveとsave!メソッドの違いについて
  • 削除
  • 参考リンク

インストール

まずはインストール。


gem install activerecord

DBはMySQLを使うのでこちらもインストール。


gem install mysql2

使い方

以下のようなテーブルを作成します。


categories  # テーブル
    id          # INT、主キー、AI
    name        # VARCHAR(20)
    created_at  # DATETIME
    updated_at  # DATETIME

product  # テーブル
    id          # INT、主キー、AI
    name        # VARCHAR(20)
    created_at  # DATETIME
    updated_at  # DATETIME

上記のテーブルをActive Recordで扱う場合の例は以下のとおり。


require 'active_record'
require 'mysql2'

# タイムゾーンの設定(Active Recordで自動的に保存される日時のタイムゾーンを設定(created_atやupdated_atなど))
ActiveRecord::Base.default_timezone = :local

# DB設定ファイルの読み込み
ActiveRecord::Base.configurations = YAML.load_file('database.yml')
ActiveRecord::Base.establish_connection('development')

# 文字コードの設定
Encoding.default_external = 'utf-8'

# to_jsonで出力する日付の文字列形式を指定
#  true  => "2005-02-01T15:15:10Z"
#  false => "2005/02/01 15:15:10 +0900"
ActiveSupport.use_standard_json_time_format = false

# categoriesテーブルに対応するモデルクラス
class Category < ActiveRecord::Base
end

# 複数形ではないproductテーブルに対応するモデルクラス
class Product < ActiveRecord::Base
    self.table_name = "product"
end

注意しておきたいのは、MySQLに作成するテーブル名は英語の複数系を用いること。Active Recordが自動で複数形の文字列に変換するので、「categories」というテーブル名に対応するモデルのクラス名は「Category」となります。ただし、対応するテーブル名を指定することも可能です。

以下は「database.yml」の内容。


development:
  adapter: mysql2
  encoding: utf8
  reconnect: true
  database: db
  pool: 5
  wait_timeout: 5
  host: localhost
  username: user
  password: pass

production:
  adapter: mysql2
  encoding: utf8
  reconnect: true
  database: db
  pool: 5
  wait_timeout: 5
  host: localhost
  username: user
  password: pass

「development」は開発用。「production」は本番用。

「reconnect: true」は設定しておかないと、途中でDBの接続が切断するのか、頻繁にリクエスト処理が失敗しました。

検索

主キーで検索


data = Category.find(123)

条件指定で検索、並び替え


where = {}
where["id"] = 123
where["name"] = "%テスト%"
list = Category.
    where("id < :id and name like :name", where).
    order("created_at", "id desc").
    select("id ,name ,created_at AS cat ,updated_at AS uat")

挿入


item = Category.new
item.name = "テスト"
item.save!

「id」はAI(Auto Increment)。

「created_at」、「updated_at」はActive Recordによって自動で登録されます。

更新


item = Category.find(123)
item.name = "テスト名称変更"
item.save!

変更されていた場合、「updated_at」はActive Recordによって自動で更新されます。

saveとsave!メソッドの違いについて

saveとsave!の違いは、保存できなかった場合の動作が異なります。

saveの場合、falseを返す。

save!の場合、例外が発生。

なお、Rubyで例外をキャッチする場合のコードは以下のとおり。(Javaのtry-catch-finally)


begin
    item = Category.find(123)
    item.name = "テスト名称変更"
    item.save!
rescue => ex
    # エラー処理
ensure
    # 終了処理
end	

削除


Category.delete(123)
# または
Category.destroy(123)

# 複数まとめて削除する場合
Category.delete([123, 124])
# または
Category.destroy([123, 124])

「delete」の方が処理が軽いです。「destroy」はActive Record側の処理を挟むので処理が重いが機能が豊富とのこと。

Active Recordの標準の削除は物理削除。

物理削除ではなく論理削除を行いたい場合は、こちら(Rails4で論理削除を手軽に実現する。 - Qiita)を参照。

参考リンク

Ruby】関連記事