MAGAZINE

ルーターマガジン

Ruby

RubyのActive RecordからMySQLのビュー(View)を扱う

2020.02.07
Pocket

こんにちは、アルバイトのarakiです.

もう年が明けて3週間ほど経ちますね. 皆さんは何か新年の行事に参加しましたか? 私は成人式に参加してきました. 成人式は退屈とよく言われますが、私の地域では著名な政治家がお話ししてくれたり、地元の高校の吹奏楽部がパフォーマンスをしてくれたりして想像よりも楽しかったです. なんであれ、今年も元気にPCの画面と向き合えるように頑張っていきたいです.

さて、今回はMySQLのビュー機能と、Rubyでそれを扱う方法について少しお話したいと思います.

ビューとは?

まず、MySQLのビュー(view)について. 簡潔に言えば、「SELECT文の結果をテーブルのようにしたもの」です. ビューはテーブルと同様に扱われるので、よく使うことのあるSELECT文はビューとして纏めてあげると便利になります.

次のような文で作ることができます.


CREATE VIEW
  view_name
  (
    column1,
    column2,
    ...
  )
AS
  SELECT
    column1_from_tables,
    column2_from_tables,
    ...
  FROM
    tables;

実際に使ってみる

今回は、rubyを使ってビューから情報を取り出してみます.

次のような、果物の情報が入ったfruitsテーブルと果物屋の情報が入ったstoresテーブルがあります.

fruitsテーブルには、name(果物の名前)、price(価格)、store_id(取り扱っている果物屋のid)が、storesテーブルには、name(果物屋の名前)、is_open(開店しているか?)が存在します.

それでは、次の文によって2つのテーブルを纏めたfruit_viewを作成します.

CREATE VIEW
  fruit_view
  (
    store_id,
    fruit_id,
    fruit_name,
    price,
    store_name,
    store_is_open
  )
AS
  SELECT
    stores.id,
    fruits.id,
    fruits.name,
    fruits.price,
    stores.name,
    stores.is_open
  FROM
    fruits
    JOIN
    stores
    ON
    fruits.store_id=stores.id;

このようなビューができました.

ちなみに、ビューに含まれているテーブルが更新されると、ビューも自動で更新されます. 試しに、fruitsテーブルに「柿」を追加してみました.

すると、ビューも更新されたのが分かります.

それでは、rubyを使って「開店している果物屋が扱っている果物で、一番安い果物の名前と値段、そして果物屋の名前を出力するプログラム」を作りましょう.

require 'active_record'
require 'pp'

# データベースとの接続処理
config = {
  adapter:  'mysql2',
  host:     'localhost',
  username: 'root',
  password: '',
  database: 'SampleDB'
}

ActiveRecord::Base.establish_connection(config)

# fruit_view
class FruitView < ActiveRecord::Base
  self.table_name = 'fruit_view' # railsの命名規則に従っていないため.
end

# 最安品を探す
min_price = FruitView.where('store_is_open = 1').minimum(:price)
min_records = FruitView.where('store_is_open = 1 AND price = ?', min_price)

# 結果の出力
result = []
min_records.each do |min_record|
  result << {
    fruit_name: min_record.fruit_name,
    price: min_record.price,
    store_name: min_record.store_name
  }
end

pp result

結果は次のようになります.


$ruby cheapest_available_fruit.rb
[{:fruit_name=>"apple", :price=>170, :store_name=>"shopA"},
{:fruit_name=>"kaki", :price=>170, :store_name=>"shopC"}]

最後に

ビューを使えば、複数テーブルにまたがる情報を一覧することができます. 更にテーブルと似た扱いをされるので、activerecordでも容易に扱えます. 皆さんもぜひ試してみてください.

それでは.

Pocket

CONTACT

お問い合わせ・ご依頼はこちらから