ひーろのアウトプットブログ

プログラミングの学習記録と開発日記です

Rspecで確認メッセージを選択する記述方法

システムスペックを書いている時に確認ダイアログを選択する方法を知らなかったので調べてみました。

前提

ruby: 2.6.6
rails: 6.0.3.5

内容

とりあえず分からないなりに書いてみると、案の定エラーがでました。

Selenium::WebDriver::Error::UnexpectedAlertOpenError

テストのビュー該当部分はこんな感じです。

= form_with model: @contact, local: true do |f|
  .form-group
    = f.label :message
    = f.text_area :message, size: '10x10', class: 'form-control'
  = f.submit '送信する', class: 'btn btn-primary', data: { confirm: '送信しますか?' }

解決方法

確認ダイアログを選択するにはaccept_confirmと使うと良いそうです。
なので、上記の「送信する」の場合にはこのようになります。

page.accept_confirm do
  click_on '送信する'
end

これで確認ダイアログを選択でき、テストを走らせたところパスしました。

ちなみに、確認ダイアログでキャンセルを選択する場合はこのように書けば良いようです。

page.dismiss_confirm do
  click_on '送信する'
end
参考

https://blog.regonn.tokyo/rails/2017-06-13-rspec-capybara/

https://qiita.com/at-946/items/403d85d45cb02615c323

ActionMailerでGmail宛にメールを送る際に発生したNet::SMTPAuthenticationErrorの解消

お問い合わせフォーム機能の作成でActionMailerを使用した。名前欄やメール欄を設けず、メッセージだけ記入して送信するシンプルな仕様で設計。
Railsガイドに沿って実装していったが、メッセージ送信時にNet::SMTPAuthenticationErrorというエラーが発生した。
調べたところGmail側の設定によるエラーだったようで、2段階認証のアプリパスワード設定の必要があった。
下記の方法で解消できた。

前提

ruby: 2.6.6
rails: 6.0.3.5

内容

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  port:                 587,
  address:              'smtp.gmail.com',
  domain:               'gmail.com',
  user_name:            '<ユーザー名>',
  password:             '<パスワード>',
  authentication:       'plain',
  enable_starttls_auto: true
}

config/environments/development.rbに自分のGmailアカウントへメールを送るための記述をする。

password: '<パスワード>',

このパスワードの入力が2段階認証で発行したアプリパスワードを入力する必要がある。

方法

googleアカウントへ行き、下記手順でアプリパスワードを発行する。
アカウント管理→セキュリティ→アプリパスワード→アプリとデバイス入力後、生成
16桁のアプリパスワードが発行されるので、先程のパスワード欄へ入力する。

環境変数

メールアドレスやパスワードをコードにそのまま記述するとセキュリティ上リスクが高いので、環境変数にいれて管理する。
環境変数の設定はターミナル上で行う。

$ vim ~/bash.profile

編集モードへ切り替え、メールアドレスとパスワードを入力する。

export EMAIL='************'
export APP_PASSWORD='*************' #発行したアプリパスワード

保存したらconfig/environments/development.rbに反映させる。

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  port:                 587,
  address:              'smtp.gmail.com',
  domain:               'gmail.com',
  user_name:            ENV['EMAIL'],
  password:             ENV['APP_PASSWORD'],
  authentication:       'plain',
  enable_starttls_auto: true
}

サーバーを再起動し問い合わせフォームからメッセージを送るとエラーが解消され、Gmailで受信できた。

参考

https://railsguides.jp/action_mailer_basics.html

https://qiita.com/aokabin/items/704fe30c33b885ac14f1

https://qiita.com/yuichir43705457/items/7cfcae6546876086b849

MySQLとバリデーションにおけるユニーク制約の違い

railsでアプリを作成していたところ、MySQLとvalidatesのユニーク制約で想定していなかった挙動をしました。

前提

ruby: 2.6.6
rails: 6.0.3.5

内容

userテーブルを作成し、ユニーク制約をかけました。

$ rails g model User name:string
class CreateUser < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name, null: false

      t.timestamps
    end
    add_index :users, :name, unique: true # ユニーク制約追記
  end
end
$ rails db:migrate
class User < ApplicationRecord
  validates :name, presence: true
  validates :name, uniqueness: true
end

一旦このバリデーションをかけました。
uniqueness: trueのバリデーションは大文字と小文字を区別するはずなので’aaaaaa’と’AAAAAA’というUserを試しにrails consoleで登録しようとしたところ、後者の登録時に、

ActiveRecord::RecordNotUnique: Mysql2::Error: Duplicate entry 'AAAAAA' for key 'index_users_on_name'

というエラーが発生しました。

解決策

どうやらMySQLでは大文字と小文字を区別しない、というのが標準の挙動だったようです。 今回は大文字と小文字を区別しない設計にしたかったのでバリデーションを変更します。

class User < ApplicationRecord
  validates :name, presence: true
  validates :name, uniqueness: true
  # case_sensitive: falseで大文字と小文字の区別をしなくなる
end

このように書き換えたあと先ほどと同じUser名を登録しようとしたところ、バリデーションが利きROLLBACKされました。