- 更新日: 2022年05月06日
- 公開日: 2021年03月27日
Active Recordでデータベースの操作をしてみよう③【limit・order編】
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のコードだけでデータベースの操作が可能になりました。本記事では、データベースから取り出したデータの並び順を変更する「order」と取り出すデータの数を指定する「limit」メソッドについて解説していきます。
準備編
まずはActive Recordについて学ぶ準備をしましょう。
ターミナル(コマンドプロンプト)を開き、下記コマンドを上から実行してください。今回は簡単にアプリケーションの雛形を作成する『Scaffold』を使用して、解説していきます。
//作業ディレクトリを作成
mkdir active_record_practice
//作業ディレクトリに移動
cd active_record_practice/
//Railsの新規プロジェクト作成
rails new Active_Record_app3
cd Active_Record_app3
// Salesmanに関する必要なフォルダを自動で作成
rails g scaffold Salesman name:string customers:integer
//データベースを作成
rails db:create
//マイグレーションを実行
rails db:migrate
rails s
rails sコマンドまで実行できたら、ブラウザで「localhost:3000」を開いてください。下画像のようになれば準備は完了です。
次にSalesmanのサンプルデータを作成していきます。ターミナルやブラウザでも新規データの作成は可能ですが、今回はseedファイルを使って進めましょう。
dbフォルダ配下の「seed.rb」を開き、下記コードを貼り付けてください。
Salesman.create([
{ name: '林', customers: 10 },
{ name: '田中', customers: 20 },
{ name: '大林', customers: 240 },
{ name: '今井', customers: 100 },
{ name: '伊東', customers: 20 },
{ name: 'マイク', customers: 35 },
{ name: '吉村', customers: 120 },
{ name: 'ジョン', customers: 200 },
{ name: '内村', customers: 160 },
{ name: '平井', customers: 80 }
])
これらのサンプルデータをデータベースに反映させるために、下記コマンドをターミナルで実行してください。
rails db:seed
これでseed.rbの内容がデータベースに保存されたはずです。確認のため、ブラウザのURLに「localhost:3000/salesmen」を入力してください。
そうすると先程作成したseed.rbのファイルの内容が反映されているのが分かります。これでActive Recordのメソッドを実行する環境が整いました。
Active Recordのメソッド① limit編
この章ではActive Recordの「limit」メソッドについてみていきましょう。limitはデータベースから取り出すデータの数を指定する際に使用するメソッドです。
まずはターミナルでrails cを実行して、コンソールを立ち上げます。「irb(main):001:0>」のようにコマンドを入力できる状態になっていればOKです。
それでは下記コマンドを実行して結果を確認してみましょう。
Salesman.all
//実行結果
> #<ActiveRecord::Relation [#<Salesman id: 1, name: "林", customers: 10, created_at: "2021-03-10 10:06:50.172726000 +0000", updated_at: "2021-03-10 10:06:50.172726000 +0000">, #<Salesman id: 3, name: "田中", customers: 20, created_at: "2021-03-10 10:10:03.757652000 +0000", updated_at: "2021-03-10 10:10:03.757652000 +0000">, #<Salesman id: 4, name: "大林", customers: 240, created_at: "2021-03-10 10:10:03.762909000 +0000", updated_at: "2021-03-10 10:10:03.762909000 +0000">,....(以下省略)
モデル名に対して、allメソッドを実行すると全てのデータを取得できます。しかし特定のデータ数のみ欲しい場合には、allメソッドは不向きです。
そこで「limit」メソッドを使用します。コンソールで下記コマンドを実行して、結果を確認してみましょう。
Salesman.limit(3)
//実行結果
=> #<ActiveRecord::Relation [#<Salesman id: 1, name: "林", customers: 10, created_at: "2021-03-10 10:06:50.172726000 +0000", updated_at: "2021-03-10 10:06:50.172726000 +0000">, #<Salesman id: 3, name: "田中", customers: 20, created_at: "2021-03-10 10:10:03.757652000 +0000", updated_at: "2021-03-10 10:10:03.757652000 +0000">, #<Salesman id: 4, name: "大林", customers: 240, created_at: "2021-03-10 10:10:03.762909000 +0000", updated_at: "2021-03-10 10:10:03.762909000 +0000">]>
limitメソッドの引数に数字を指定すると、その数だけデータを取得可能です。例えばlimit(3)とすると、データの先頭から3つを取り出します。
またlimitメソッドは同じくActive Recordのメソッドである「offset」と組み合わせてしようされる場合があります。コンソールで下記コマンドを実行して、結果を確認してみましょう。
Salesman.limit(3).offset(1)
//実行結果
=> #<ActiveRecord::Relation [#<Salesman id: 3, name: "田中", customers: 20, created_at: "2021-03-10 10:10:03.757652000 +0000", updated_at: "2021-03-10 10:10:03.757652000 +0000">, #<Salesman id: 4, name: "大林", customers: 240, created_at: "2021-03-10 10:10:03.762909000 +0000", updated_at: "2021-03-10 10:10:03.762909000 +0000">, #<Salesman id: 5, name: "今井", customers: 100, created_at: "2021-03-10 10:10:03.769158000 +0000", updated_at: "2021-03-10 10:10:03.769158000 +0000">]>
結果をみてみると、idが3のデータから3つ取り出されているのが分かります。このようにoffsetメソッドを使うと、どのデータから取り出すか指定できます。
ちなみにoffsetの引数とデータの順番は一致しません。例えば3番目(インデックス番号が2)のデータから取得したい場合は、offset(1)とする必要があります。
つまりoffsetの引数は「取り出したいデータの順番-2」となっています。
Active Recordのメソッド② order編
次は「order」メソッドについてみていきましょう。orderメソッドは、データベースから取り出すデータの順番を変える役割があります。
早速コンソールで下記コマンドを実行してください。
Salesman.order(id: :desc)
//実行結果
=> #<ActiveRecord::Relation [#<Salesman id: 11, name: "平井", customers: 80, created_at: "2021-03-10 10:10:03.804425000 +0000", updated_at: "2021-03-10 10:10:03.804425000 +0000">, #<Salesman id: 10, name: "内村", customers: 160, created_at: "2021-03-10 10:10:03.798589000 +0000", updated_at: ……(以下省略)
結果を確認すると、idが大きい順に取り出していることが分かります。このようにorderの引数に「カラム: :desc」とすると、カラムの値が大きい順にデータを並び替えます。
いいね獲得数やレビュー数などによって、表示を並び替えることができるので、非常に便利なメソッドです。
コントローラーでorderメソッドを使ってみよう
この章では、Active Recordのメソッドをコントローラーで使用する方法について解説していきます。この章のゴールは、「localhost:3000/salesmen」で下画像のように、新規顧客の数が多い順に表示させることです。
実装内容としては、①customers(新規に獲得した顧客)が多い順に表示②順位を表示③順位に応じて社長からの言葉を変えるの3点です。
それでは、app / controllers / salesmen.rbを開き、下記コードをindexアクションに貼り付けてください。
def index
@salesmen = Salesman.order(customers: :desc)
end
customersが多い順に並び替えたいので、orderの引数に「customers: :desc」を指定しています。次にViewを変更していきましょう。
app / views / index.html.erbを開き、下記コードに書き換えてください。
<p id="notice"><%= notice %></p>
<h1>営業成績</h1>
<table>
<thead>
<tr>
<th>順位</th>
<th>名前</th>
<th>新規に獲得した顧客</th>
<th>社長からの言葉</th>
<th colspan="4"></th>
</tr>
</thead>
<tbody>
<% @salesmen.each.with_index(1) do |salesman,index| %>
<tr>
<td><%= index %></td>
<td><%= salesman.name %></td>
<td><%= salesman.customers %></td>
<% if index <= 3%>
<td>よく頑張りましたね!</td>
<% elsif 3 < index && index <= 7 %>
<td>次は頑張りましょう。</td>
<% else %>
<td>残念です。</td>
<% end %>
<td><%= link_to 'Show', salesman %></td>
<td><%= link_to 'Edit', edit_salesman_path(salesman) %></td>
<td><%= link_to 'Destroy', salesman, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Salesman', new_salesman_path %>
今回は順位を表示させるために、「配列のインデックス番号」と「配列の要素」の2つを取り出します。そのためeach_with_index(1)メソッドを使用します。each_with_index()の引数に1を指定することで、取り出すインデックスが1から始まります。
引数に1を指定しない場合は、インデックス番号が0から始まるので、下記コードのように修正する必要があります。
<tbody>
<% @salesmen.each.with_index do |salesman,index| %>
<tr>
<td><%= index + 1 %></td>
「localhost:3000/salesmen」にアクセスして、下画像が表示されれば成功です。
\Rubyでのサービス開発スキルが身に付く/
まとめ
Active Recordのlimitとorderメソッドについて、学習してきました。limitやorderを使うことで、複雑なSQLのコマンドを実行せずに、ランキング機能などを実装可能です。
ぜひ本記事で学んだ内容を復習してみてはいかがでしょうか。
- この記事を書いた人
- ヤマモト