2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsチュートリアル第6章 備忘録_前編

2
Last updated at Posted at 2021-03-17

経緯

個人的にこの章から正規表現を初め、難易度がかなり上がった気がする。
バリデーションテェックなど、外したくない部分が多々あったので
確実に理解していくため2回に分けて深掘ろうと思う。

Userモデル

Railsでは、データモデルとして扱うデフォルトのデータ構造のことをモデル(Model)と呼ぶ。
データベースとやりとりをするデフォルトのRailsライブラリはActive Recordと呼ぶ。
Active Recordのおかげで通常データベースを操作するのに必要なSQLを意識する必要がない。
コントローラ名には複数形(Users)
モデル名には単数形(User)
を用いる。

Userモデルの生成
$ rails generate model User name:string email:string

generateコマンドの結果のひとつとして、マイグレーションと呼ばれる新しいファイルが生成される。
マイグレーションは、データベースの構造を切り離し、要求が変更された場合にデータモデルを適合できる。

users
id integer
name string
email string
created_at datetime
updated_at datetime

マイグレーション実行コマンド
$ rails db:migrate
やっぱ元に戻したい
$ rails db:rollback

modelファイル

app/models/user.rb

class User < ApplicationRecord
end

User < ApplicationRecord < ActiveRecord::Base
つまり、ActiveRecord::Baseクラスのすべての機能を持つことになる。

データベースを変更せずにデータモデルを調べるときは、
$ rails console --sandbox を使う。
コンソール終了時に変更をすべてロールバック(取消)してくれる。

ユーザーオブジェクトをコンソール用に出力

  • 引数なし:すべての属性がnilで返ってくる。
    >> User.new

  • 引数あり (初期化hash)
    >> user = User.new(name: "Michael Hartl", email: "michael@example.com")

有効性(Validity) : オブジェクトが有効かどうか
>> user.valid?

User.newで作成したUserオブジェクトを保存
>> user.save
saveしない限り、created_at,updated_atはnilのまま

Userモデルのインスタンスはドット記法を用いてその属性にアクセス可能。
>> user.name
>> user.email
>> user.updated_at

作成と保存が同時にやりたい
>> User.create
削除
>> User.destroy

ユーザーオブジェクトを検索

Active Recordには、オブジェクトを検索するための方法がいくつもある。

過去に作成したユーザーを探す
>> User.find(ユーザID)

特定の属性でユーザーを検索する
>> User.find_by(属性: "属性に対する値")

最初のユーザ
>> User.first

ユーザ全員
>> User.all

ユーザの要素数を知りたい(メソッドチェーンを使用)
>> User.all.length

ユーザーオブジェクトを更新

・直接代入してsave
>> user.name = "Michael Hartl"
>> user.save

・updateメソッド使用
>>user.update(name: "Michael Hartl", email: "michael@example.com")

・特定の属性のみを更新したい場合(データの「検証」を回避する効果がある)
>> user.update_attribute(:name, "Michael Hartl")

ユーザーを検証する

要はバリデーションチェックのこと。

  • 存在性(presence)の検証
  • 長さ(length)の検証
  • フォーマット(format)の検証
  • 一意性(uniqueness)の検証
  • 確認(confirmation) -> よく使われる最終検証

失敗するテストを書き、次にテストを成功させるように実装する。(テスト駆動開発)

有用性を検証する

test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com")
  end

  test "should be valid" do
    assert @user.valid?
  end
end

setupメソッドを使ってUserオブジェクト(@user)を作成。これは各テストが走る直前に実行される。
@userをsetupメソッド内で宣言。
should be validで、@userの有効性をテストできる。

modelに関係するテストだけ走らせたい場合のコマンド
$ rails test:models

Userモデルにはまだバリデーションがないので、このテストは成功する。

存在性を検証する

最も基本的なバリデーション。

test/models/user_test.rb
省略
  test "name should be present" do
    @user.name = "     "
    assert_not @user.valid?
  end
省略

空白を入れ、nameが存在しない場合はuserが有効でない。

現段階でテストは失敗。

app/models/user.rb
class User < ApplicationRecord
  validates :name, presence: true
end

  #validates(:name, presence: true)の省略形

コンソールにて、valid?メソッドでuser変数が有効かどうかチェック。
$ rails console --sandbox``` >> user = User.new(name: "", email: "michael@example.com") >> user.valid? => false``

失敗したときに作られるerrorsオブジェクトを使ってみる
>> user.errors.full_messages
=> ["Name can't be blank"]

有効でないuserがデータベースに保存できないことを確認
>> user.save
=> false

テストも成功する。

長さを検証する

ユーザー名:50文字以内で制限
メールアドレス:255文字以内で制限

test/models/user_test.rb
省略
  test "name should not be too long" do
    @user.name = "a" * 51
    assert_not @user.valid?
  end

  test "email should not be too long" do
    @user.email = "a" * 244 + "@example.com"
    assert_not @user.valid?
  end
省略

aを掛け算で増やして文字数を稼いでいる。

この時点ではテスト失敗

app/models/user.rb
class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 50 }
  validates :email, presence: true, length: { maximum: 255 }
end

テスト成功する。

フォーマットを検証する

メールアドレスにおなじみのパターンuser@example.comに合っているかどうか確認する。

%w[]を使うと文字列の配列を簡単に作れる.
これを使って無効なメールアドレスリストを作成していく。

test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com")
  end
  .
  .
  .
  test "email validation should accept valid addresses" do
    valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
                         first.last@foo.jp alice+bob@baz.cn]
    valid_addresses.each do |valid_address|
      @user.email = valid_address
      assert @user.valid?, "#{valid_address.inspect} should be valid"
      #どのメールアドレスでテストが失敗したか特定できるよう、assertメソッドの第二引数でエラーメッセージを追加している。
    end
  end
end

user@example,com(ドットではなくカンマになっている)や
user_at_foo.org(アットマーク ‘@’ がない)といった無効なメールアドレスを使って
「無効性(Invalidity)」についてテスト

test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com")
  end
  .
  .
  .
  test "email validation should reject invalid addresses" do
    invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
                           foo@bar_baz.com foo@bar+baz.com]
    invalid_addresses.each do |invalid_address|
      @user.email = invalid_address
      assert_not @user.valid?, "#{invalid_address.inspect} should be invalid"
    end
  end
end

テストは失敗。

メールアドレスのフォーマットを検証するためには正規表現を書かなければならない。

app/models/user.rb
class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i  #VALID_EMAIL_REGEX:定数
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX }
end

残念な点:foo@bar..comのようなドットの連続を誤りとして検出できない.

テストが通る。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?