Active Recordでデータベースの操作をしてみよう③【limit・order編】


Active Recordでデータベースの操作をしてみよう③【limit・order編】

Ruby on Rails(以下Railsと呼ぶ)には、データの操作を簡単にする『Active Record』という便利な機能があります。プログラミング初心者の中には、Active Record特有のfindやwhereメソッドの扱いに苦手意識を感じている方もいるかもしれません。

本記事は、簡単なアプリケーションを作成しながら、Active Recordやデータベースの操作を学べるようになっていますので、ぜひこの機会に理解を深めていただければと思います。

目次
  1. 準備編
  2. Active Recordのメソッド① limit編
  3. Active Recordのメソッド② order編
  4. コントローラーでorderメソッドを使ってみよう
  5. まとめ

『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」を開いてください。下画像のようになれば準備は完了です。

image

次に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」となっています。

202106キャンペーン

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」で下画像のように、新規顧客の数が多い順に表示させることです。

image

実装内容としては、①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」にアクセスして、下画像が表示されれば成功です。

image

Rubyでのサービス開発スキルが身に付く

CodeCampの無料体験はこちら

まとめ

Active Recordのlimitとorderメソッドについて、学習してきました。limitやorderを使うことで、複雑なSQLのコマンドを実行せずに、ランキング機能などを実装可能です。

ぜひ本記事で学んだ内容を復習してみてはいかがでしょうか。


関連記事

ヤマモト
この記事を書いた人
ヤマモト
\ 無料体験開催中!/自分のペースで確実に習得!
オンライン・プログラミングレッスンNo.1のCodeCamp