- 更新日: 2021年03月27日
- 公開日: 2021年03月25日
Active Recordでデータベースの操作をしてみよう②【select・group編】
Ruby on Rails(以下Railsと呼ぶ)には、データの操作を簡単にする『Active Record』という便利な機能があります。プログラミング初心者の中には、Active Record特有のfindやwhereメソッドの扱いに苦手意識を感じている方もいるかもしれません。
本記事は、簡単なアプリケーションを作成しながら、Active Recordやデータベースの操作を学べるようになっていますので、ぜひこの機会に理解を深めていただければと思います。
『Active Record』は、Rubyとデータベースの言語であるSQLを繋ぐ翻訳機のような役割をします。本来データベースからデータの取得や削除などをおこなうには、SQLのコマンドの実行が必要がです。
しかしSQLのコマンドは複雑である場合が多く、どうしてもSQLの知識が必要となります。そこで生まれたのが『Active Record』です。
Active Recordにより、SQLのコードを書かずに、Rubyのコードだけでデータベースの操作が可能になりました。本記事では、データの集計や特定のカラムのみ抽出するのを可能にする「select」と「group」メソッドについて解説していきます。
また「find」や「where」メソッドに関しても別記事で解説しておりますので、ぜひこちらも参考にしてみてください。
準備編
まずはActive Recordについて学ぶ準備をしましょう。
ターミナル(コマンドプロンプト)を開き、下記コマンドを上から実行してください。今回は簡単にアプリケーションの雛形を作成する『Scaffold』を使用して、解説していきます。
//作業ディレクトリを作成
mkdir active_record_practice
//作業ディレクトリに移動
cd active_record_practice/
//Railsの新規プロジェクト作成
rails new Active_Record_app2
cd Active_Record_app2
// Bookに関する必要なフォルダを自動で作成
rails g scaffold Book lang:string title:string price:integer
//データベースを作成
rails db:create
//マイグレーションを実行
rails db:migrate
rails s
rails sコマンドまで実行できたら、ブラウザで「localhost:3000」を開いてください。下画像のようになれば準備は完了です。
次にBookのサンプルデータを作成していきます。ターミナルやブラウザでも新規データの作成は可能ですが、今回はseedファイルを使って進めましょう。
dbフォルダ配下の「seed.rb」を開き、下記コードを貼り付けてください。
Book.create([
{id:1,lang:"ruby",title:"Rubyは楽しいぞ!",price:1200},
{id:2,lang:"python",title:"Pythonで自動化しよう!",price:1100},
{id:3,lang:"javascript",title:"Javascriptでサイトに動きをつけよう!",price:1200},
{id:4,lang:"ruby",title:"RubyでWebアプリを作ろう",price:1500},
{id:5,lang:"python",title:"Pythonでデータ分析",price:2000},
{id:6,lang:"javascript",title:"入門Javascript",price:1500},
{id:7,lang:"javascript",title:"jQuery入門",price:1300},
{id:8,lang:"ruby",title:"Rubyのクラスを学ぼう",price:1400},
{id:9,lang:"python",title:"pythonでスクレイピング",price:1600},
{id:10,lang:"php",title:"楽しいPHP",price:2000}
])
これらのサンプルデータをデータベースに反映させるために、下記コマンドをターミナルで実行してください。
rails db:seed
これでseed.rbの内容がデータベースに保存されたはずです。確認のため、ブラウザのURLに「localhost:3000/books」を入力してください。
そうすると先程作成したseed.rbのファイルの内容が反映されているのが分かります。これでActive Recordのメソッドを実行する環境が整いました。
Active Recordのメソッド① select編
この章ではActive Recordの「select」メソッドについてみていきましょう。selectはデータベースから特定のカラムに入っているデータのみ抽出する際に使用するメソッドです。
まずはターミナルでrails cを実行して、コンソールを立ち上げます。「irb(main):001:0>」のようにコマンドを入力できる状態になっていればOKです。
それでは下記コマンドを実行して結果を確認してみましょう。
Book.all
//実行結果
=> #<ActiveRecord::Relation [#<Book id: 1, lang: "ruby", title: "Rubyは楽しいぞ!", price: 1200, created_at: "2021-03-09 03:12:33.202691000 +0000", updated_at: "2021-03-09 03:12:33.202691000 +0000">, #<Book id: 2, lang: "python", title: "Pythonで自動化しよう!", price: 1100, created_at: "2021-03-09 03:12:33.209837000 +0000", updated_at: "2021-03-09 03:12:33.209837000 +0000">, #<Book id: 3, lang: "javascript", title: "Javascriptでサイトに動きをつけよう!", price: 1200, created_at: "2021-03-09 03:12:33.214840000 +0000", updated_at: "2021-03-09 03:12:33.214840000 +0000">,.......(以下省略)
モデル名に対して、allメソッドを実行すると全てのデータを取得できます。しかしid・lang・titleのデータのみ抜き出したい場合には、allメソッドを使うのは適切でありません。
なぜなら不必要な情報を取得すると、それだけメモリのリソースを圧迫するからです。今回はデータが10件なので、allを使っても問題ないですが、何万件という大量のデータの場合パフォーマンスが大幅に落ちるでしょう。
そこで「select」メソッドが役に立ちます。コンソールで下記コマンドを実行して、結果を確認してみましょう。
Book.select(:id,:lang,:title)
//実行結果
=> #<ActiveRecord::Relation [#<Book id: 1, lang: "ruby", title: "Rubyは楽しいぞ!">, #<Book id: 2, lang: "python", title: "Pythonで自動化しよう!">, #<Book id: 3, lang: "javascript", title: "Javascriptでサイトに動きをつけよう!">, #<Book id: 4, lang: "ruby", title: "RubyでWebアプリを作ろう">, #<Book id: 5, lang: "python", title: "Pythonでデータ分析">, #<Book id: 6, lang: "javascript", title: "入門Javascript">, #<Book id: 7, lang: "javascript", title: "jQuery入門">, #<Book id: 8, lang: "ruby", title: "Rubyのクラスを学ぼう">, #<Book id: 9, lang: "python", title: "pythonでスクレイピング">, #<Book id: 10, lang: "php", title: "楽しいPHP">]>
このようにselectメソッドを実行することで、無駄な情報を省きメモリのリソースを節約できます。
またselectメソッドは、whereやfindメソッドと組み合わせて使用することも可能です。コンソールで下記コマンドを実行してください。
Book.where(price:1200).select(:id,:lang,:title,:price)
//実行結果
=> #<ActiveRecord::Relation [#<Book id: 1, lang: "ruby", title: "Rubyは楽しいぞ!", price: 1200>, #<Book id: 3, lang: "javascript", title: "Javascriptでサイトに動きをつけよう!", price: 1200>]>
先程実行したコマンドは、①priceが1200のデータのみ抽出 ②①で取得したデータから、id・lang・title・priceのみ抽出をおこなっています。selectメソッドに限らず、Active Recordのメソッド同士を組み合わせることで、より複雑な条件の検索が可能です。
Active Recordのメソッド② group編
次はgroupメソッドについてみていきましょう。groupメソッドは、特定のキーで結果をグループ化できます。
Bookモデルのlangカラムには、「ruby」「python」「javascript」「php」の4つが存在します。例えば、langの種類毎の価格の合計値を出したい場合に、「group」メソッドは有効です。
コンソールで下記コマンドを実行して、結果を確認してみましょう。
Book.group(:lang).sum(:price)
//実行結果
=> {"javascript"=>4000, "php"=>2000, "python"=>4700, "ruby"=>4100}
言語毎の価格の合計値を算出できました。このようにgroupメソッドは、sum(カラムの合計値を表示)などの集計関数と使います。
合計値だけでなく、最大値や平均値を求めることも可能です。
Book.group(:lang).maximum(:price)
=> {"javascript"=>1500, "php"=>2000, "python"=>2000, "ruby"=>1500}
Book.group(:lang).minimum(:price)
=> {"javascript"=>1200, "php"=>2000, "python"=>1100, "ruby"=>1200}
Book.group(:lang).ave(:price)
注)eは10を指し、e4であれば10の4乗という意味になります。
=> {"javascript"=>0.133333333333333e4, "php"=>0.2e4, "python"=>0.156666666666667e4, "ruby"=>0.136666666666667e4}
またgroupとcountメソッドを組み合わせることで、同じ種類のデータが何個あるのか算出可能です。
Book.group(:lang).count
=> {"javascript"=>3, "php"=>1, "python"=>3, "ruby"=>3}
このようにgroupメソッドは、複雑なデータの処理を簡単にできる強力な機能です。
コントローラーでgroupメソッドを使ってみよう
この章では、Active Recordのメソッドをコントローラーで使用する方法について解説していきます。この章のゴールは、「localhost:3000/books」で下画像のように、価格の平均値と合計値を表示させることです。
まずは、app / controllers /books_controller.rbを開き、indexアクションを下記コードのように変更してください。
def index
@books = Book.all
@ave_books = Book.group(:lang).average(:price)
@sum_books = Book.group(:lang).sum(:price)
end
次にapp / views /books / index.html.erbを開き、下記コードを貼り付けてください。コードの中にある「round」は数値を四捨五入するメソッドです。
<%# 平均価格 %>
<h1>Average Books</h1>
<table>
<thead>
<tr>
<th>Lang</th>
<th>Average Price</th>
<th colspan="2"></th>
</tr>
</thead>
<tbody>
<% @ave_books.each do |key,value| %>
<tr>
<td><%= key %></td>
<td><%= value.round %></td>
</tr>
<% end %>
</tbody>
</table>
<%# 合計価格 %>
<h1>Sum Books</h1>
<table>
<thead>
<tr>
<th>Lang</th>
<th>Sum Price</th>
<th colspan="2"></th>
</tr>
</thead>
<tbody>
<% @sum_books.each do |key,value| %>
<tr>
<td><%= key %></td>
<td><%= value.round %></td>
</tr>
<% end %>
</tbody>
</table>
「localhost:3000/books」にアクセスして、下画像が表示されれば成功です。
\Webサイト担当者としてのスキルが身に付く/
まとめ
Active Recordのselectとgroupメソッドについて、学習してきました。selectやgroupは、データベースの言語であるSQLのコードを書かなくても、複雑なデータ処理ができる便利なメソッドです。
他にもorderメソッドなどと組み合わせると、ランキング機能などの実装も可能になります。ぜひ本記事で学んだ内容を復習してみてはいかがでしょうか。
- この記事を書いた人
- ヤマモト