質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Model

MVCモデルの一部であるModelはアプリケーションで扱うデータとその動作を管理するために扱います。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

2898閲覧

モデルにない属性のバリデーションのテスト方法について

Tkahiro_Oda

総合スコア7

Model

MVCモデルの一部であるModelはアプリケーションで扱うデータとその動作を管理するために扱います。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2017/04/14 05:07

編集2017/04/14 09:09

※当方、rails5から入った初心者です。ですのでruby自体も初心者です。

###前提・実現したいこと

お問い合わせフォームのバリデーションのテストうち、モデルにない属性(確認ボタン)のバリデーションがうまくいかないです。

お問い合わせフォームは以下の要素を持っています。

  • 名前
  • メールアドレス
  • 本文
  • 確認ボタン
  • 送信ボタン

DBに保存するのは、名前、メールアドレス、本文のみです。

###該当のソースコード

※FactoryGirlの接頭辞は省略するように設定しています。

ruby

1# app/views/contacts/index.html.slim 2 3h1 お問い合わせ 4 5= form_for @contact do |f| 6 7 - if @contact.errors.any? 8 = "#{pluralize(@contact.errors.count, 'error')}" 9 ul 10 - @contact.errors.full_messages.each do |msg| 11 li = msg 12 13 = f.label :name, '名前' 14 = f.text_field :name 15 16 br 17 18 = f.label :email, 'メールアドレス' 19 = f.email_field :email 20 21 br 22 23 = f.label :body, '内容' 24 = f.text_area :body 25 26 br 27 28 = f.label :confirmation, '確認' 29 = f.check_box :confirmation 30 31 br 32 33 = f.submi

ruby

1# app/models/contact.rb 2 3class Contact < ApplicationRecord 4 attr_accessor :confirmation 5 validates :name, presence: true 6 VALIDE_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i 7 validates :email, presence: true, format: { with: VALIDE_EMAIL_REGEX } 8 validates :body, presence: true 9 validates :confirmation, acceptance: true 10end

ruby

1# db/migrate/2017040455604_create_contacts.rb 2 3class CreateContacts < ActiveRecord::Migration[5.0] 4 def change 5 create_table :contacts do |t| 6 t.string :name, :null => false, :limit => 200 7 t.string :email, :null => false, :limit => 200 8 t.text :body, :null => false 9 10 t.timestamps 11 end 12 end 13end

ruby

1# spec/factories/contacts.rb 2 3FactoryGirl.define do 4 factory :contact do 5 name "bcafe" 6 email "bcafe-to@example.com" 7 body "this is test." 8 9 factory :contact_with_empty_name do 10 name nil 11 end 12 13 factory :contact_with_empty_email do 14 email nil 15 end 16 17 factory :contact_with_empty_body do 18 body nil 19 end 20 21 factory :contact_with_empty_confirmation do 22 confirmation nil 23 end 24 end 25end

ruby

1# spec/models/contact_spec.rb 2 3require 'rails_helper' 4 5RSpec.describe Contact, type: :model do 6 describe 'validation' do 7 it 'is valid with name, email, body and confirmation' do 8 contact = build(:contact) 9 expect(contact).to be_valid 10 end 11 12 it 'is invalid without name' do 13 contact = build(:contact_with_empty_name) 14 contact.valid? 15 expect(contact.errors[:name].any?).to be true 16 end 17 18 it 'is invalid without email' do 19 contact = build(:contact_with_empty_email) 20 contact.valid? 21 expect(contact.errors[:email].any?).to be true 22 end 23 24 it 'is invalid without body' do 25 contact = build(:contact_with_empty_body) 26 contact.valid? 27 expect(contact.errors[:body].any?).to be true 28 end 29 30 it 'is invalid without confirmation' do 31 contact = build(:contact_with_empty_confirmation) 32 contact.valid? 33 expect(contact.errors[:confirmation].any?).to be true 34 end 35 end 36 37 describe 'database' do 38 it 'should save contact instance with no abnormality' do 39 assert build(:contact).save 40 end 41 42 it 'should not save contact instance with epmty name' do 43 contact = build(:contact_with_empty_name) 44 expect { contact.save!(validate: false) }.to raise_error ActiveRecord::StatementInvalid 45 end 46 47 it 'should not save contact instance wihout email' do 48 contact = build(:contact_with_empty_email) 49 expect { contact.save!(validate: false) }.to raise_error ActiveRecord::StatementInvalid 50 end 51 52 it 'should noe save contact instance withoud body' do 53 contact = build(:contact_with_empty_body) 54 expect { contact.save!(validate: false) }.to raise_error ActiveRecord::StatementInvalid 55 end 56 end 57end 58

###発生している問題・エラーメッセージ

Failures: 1) Contact validation is invalid without confirmation Failure/Error: expect(contact.errors[:confirmation].any?).to be true expected true got false # ./spec/models/contact_spec.rb:31:in `block (3 levels) in <top (required)>'

###補足情報(言語/FW/ツール等のバージョンなど)

  • ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]
  • Rails 5.0.2
  • RSpec 3.5.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

確認ボタンと聞くと、そこはかとなくレガシーのいやな感じがしますが…。
とりあえず、下記の規約に同意する等のconfirmだと思うことにしますね。

基本的に、ActiveRecordはtableに紐づいているので
送信ボタン(submit)を除いて存在しない、columnのvalidationはできません。

もしやりたい場合はActiveModelというClassを使うか、DraperといったPresenterを使い
ActiveRecordを拡張してやる必要があります。Railsをしっかりやる場合、両方覚えておいて損はないでしょう

しかし、逆の発想も可能で、登録時しか使わない、columnをtableに作ってしまうという方法です。

たかだか、不要なbooleanのcolumnが一つ増えたところで、テーブル設計がどうだというのでしょうか。

Ruby on Railsはパッと組み立て、サクッと動かせ、ちょちょっと直せるので、
ベストな方法を求め枝葉末節にこだわるより、動かして、その魅力を体感してください。

投稿2017/04/14 16:05

moke

総合スコア2241

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tkahiro_Oda

2017/04/15 04:06

やはりできないのですね。 提示して頂いた、ActiveModelとDraperについて学習します。ありがとうございました。
moke

2017/04/15 05:28

ActiveModelやDraperはRubyに慣れていないと学習コストが高いので 頭を柔らかくした方がいいと思いますが…。 不要なcolumnを一つ追加して、とりあえず運用して、あとで ActiveModel等に切り替えてもテストはほとんど変わらないで適用できますし…。 個人的には、そんなにキッチリしたいならSpring javaとかでやればいいのかなーと思ってしまいます。 まあ、こだわり方は人それぞれですし、ActiveModelもDraperいいものなので、とりあえず頑張ってください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問