Ruby
RubyOnRails

初心者のためのRailsのデータ操作

この記事の続きです。
https://qiita.com/chocode/items/2793916fb139a641f735

前回の記事でDBも含めた構築を終わらせたので、今回はDBとのやり取りをまとめます。
前回と同じく身内で共有するための記事なので文章は適当。

前提条件

Userモデルを作成し、migrationファイルの中でname・passカラムが設定されているものとします。

class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :User do |t|
      t.string :name
      t.string :pass
      t.timestamps
    end
  end
end

また、seeds.rbでテストデータを設定しておく。

User.create(:name => "hoge", :pass => "fuga")
User.create(:name => "huge", :pass => "foga")

データ表示

Userモデルの全データを取得するのはUser.allで行える。
まずはcontrollerで対象ページのアクションに以下を加える。

@users = User.all

インスタンス変数なので変数名の前に@を付けるのを忘れずに。
後は@￰usersの中身をeach文で表示させるだけ。

<table>
 <thead>
  <tr>
   <td>name</td>
   <td>pass</td>
  </tr>
 </thead>
 <tbody>
  <% @users.each do |user| %>
   <tr>
    <td><%= user.name %></td>
    <td><%= user.pass %</td>
   </tr>
  <% end %>
 </tbody>
</table>

<% %>と<%= %>は、erbファイルでRubyのコードを埋め込み為の記法。
<% %>は、中身のコードをそのまま埋め込む(if文やeach文などを埋め込む)
<%= %>は、中身のコードの結果を埋め込む(主に出力したい変数を埋め込む)

データ入力

DBにデータを追加できるデータ入力ページが必要である。

まずはデータ生成用のアクションをcontrollerに加える。
ここではuser_createとしてますが、勿論アクション名は何でも良いです

def user_create

end

次にデータ入力フォームをViewに追加する。

<%= form_tag("/user_create") do %>
 <span>name</span>
 <input type="text" name="name"></input>
 <span>pass</span>
 <input type="text" name="pass"></input>
 <input type="submit" value="登録"><input>
<% %>

form_tagはpost先のアクションを指定するformタグの代わりです。<%= %>の方で囲むのに注意してください。
<input type="text">が入力フォーム。ここのname属性が変数名になる。
<input type="submit">が登録ボタン。type="button"じゃないので注意。

次にcontrollerで設定したデータ生成用アクションの中身を作っていく。

def user_create
 User.create(:name => params[:name], :pass => params[:pass])
end

name="name"のinputタグに入っていたデータがparams[:name]に代入されている。passも同様。

最後にuser_createへのroutingを追加する。これを忘れるとform_tagからuser_createまで飛ばない。

post "user_create" => "home#user_create"

getではなくpostで用意するのに注意。データと一緒にroutingする場合はpostで書くことになる。

これで入力フォームからデータが追加できるようになっているはず。

バリデーション設定

データを入力できると言っても、このままではフォームに何も入力しないまま「登録」ボタンを推すことが出来てしまう。
Userモデルで、「空のデータは登録させない」というようなルールを設定しておけば、このような不正入力を拒否する事ができる。この設定がバリデーション

Userモデルのバリデーションは、./app/models/user.rbで設定する事ができる。
今回は以下のように設定する。

class User < ApplicationRecord
 validates :name, {presence: true, length: { maximum: 10 }}
 validates :pass, {presence: true, length: { minimun: 7 }}
end

この設定では、nameは「空ではなく10文字以内」、passは「空ではなく7文字以上」というルールが適応されており、これに違反するようなデータはsaveされなくなる(当然createもダメ)

varidatesの詳しい説明はこちら
https://qiita.com/shunhikita/items/772b81a1cc066e67930e

どんなルールが設定できるかは、リファレンス見て下さい
http://railsdoc.com/references/validates

一覧ページへの移動・flashメッセージ

データを登録した後は、データ一覧ページに飛ばす方が親切です。
指定のページに飛ばすにはredirect_toを使いましょう。
user_createが実行された時に、"/user_list"ページに飛ばす場合はこう書く。

def user_create
 User.create(:name => params[:name], :pass => params[:pass])
 redirect_to("/user_list")
end

"/user_list"ページに、「ユーザが登録できました!」と表示出来たら良いですよね。
こういう時はflashメッセージを使うのが良いと思います。
flashメッセージは一回だけ表示されるメッセージで、リロードしたりページが変わると消える一時的なメッセージです。

bootstrapを使っている場合は、この記事が分かりやすい。
https://qiita.com/Yama-to/items/4d19a714d8bf5bfbabdd

噛み砕いて説明すると
application_controller.rbに以下の一行を追加して

add_flash_types :success, :info, :warning, :danger

user_createアクションの中でflashメッセージを代入して

def user_create
 User.create(:name => params[:name], :pass => params[:pass])
 flash[:success] = "ユーザが登録出来ました!" //ココ
 redirect_to("/user_list")
end

データを表示させるeach文の上にflashを表示させればOK(下のコードをコピペすれば、全flashデータが表示されます)

<% flash.each do |message_type, message| %>
 <div class="alert alert-<%= message_type %>"><%= message %></div>
<% end %>
<table>
 //省略
</table>

おわりに

実際に入力フォームページを作る場合には、ここで書かれた他にも
・データがバリデーションで弾かれた時の処理
・データ一覧からの編集・削除処理を出来るようにする
・バリデーション違反時にエラーメッセージを表示
などなど沢山やることがあると思いますが、調べれば簡単に実装方法が出てくると思います。
DBとのやり取りが出来るようになれば、rails入門は卒業と言っても良いんじゃないですかねぇ…(初心者の私が言えることじゃないですが)