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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

Q&A

解決済

1回答

523閲覧

【Rails】フォーム入力後エラー画面になるもののバリデーション突破して、ひらがなが登録できてしまう問題

Romay

総合スコア40

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

0グッド

1クリップ

投稿2019/04/19 20:56

前提・実現したいこと

Ruby 2.4.5
Rails 4.2.8
本番環境:heroku postgreSQL
開発環境:mySQL

ユーザーがユーザ情報編集のためフォームを入力後、送信するも、バリデーションに引っかかってエラー画面に移る。
しかし、もう一度ユーザー編集画面に戻ると、バリデーションをかけているはずなのに登録できてしまっている。

上記が現状発生している問題です。

以下フロー

  1. users/edit.html.erbでユーザーが情報を編集(friendly_id(ユーザーがURLを決定できるGem)を編集し英数字で文字列を決定)

2. ユーザーが英数字ではなく、ひらがな(例:あいうえお)を入力し送信
3. エラー画面に遷移
4 送信したひらがなをfriendly_idに当てはめて(例:http://localhost:3000/users/あいうえお)アクセスすると、アクセスできてしまう。(つまりひらがな「あいうえお」がfriendly_idにupdateされている)

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

ローカル環境では、This page isn’t working というエラー
Herokuでは、Application error An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details. You can do this from the Heroku CLI with the command
というエラー

該当のソースコード

ユーザ情報編集画面
users/edit.html.erb

erb

1<%= form_for @user do |f| %> 2 <div class="modal-body"> 3 <div class="error-message"></div> 4 <label> 5 <span class="btn">アイコン画像 6 <%= f.file_field :avatar ,:style=>"display:none;" , id: 'avatar_img' %> 7 </span> 8 <div class="image-edit"> 9 <img id="avatar_img_prev" src="#" class='hidden' /> 10 <%= image_tag(@user.avatar(:medium), :size => "70x70", :class => " avatar_present_img") %> 11 </div> 12 </label> 13 <ul style="list-style: none; padding-left: 0;"> 14 <li><i class="fa fa-user"></i> ユーザー名<%= f.text_field :nickname, placeholder: "ニックネーム", :required => true %></li> 15 <li><i class="fa fa-link"></i> URL (3~20文字英数字)<%= f.text_field :friendly_url, placeholder: "URLを設定(英数字3-20文字)" , :required => true %></li> 16 <li><i class="fa fa-twitter"></i> Twitter<%= f.text_field :twitter, placeholder: "@以下だけを入力" %></li> 17 <li><i class="fa fa-instagram"></i> Instagram<%= f.text_field :instagram, placeholder: "@以下だけを入力" %></li> 18 <li><i class="fa fa-comment"></i> プロフィール<%= f.text_area :description, placeholder: "100文字以内で入力" %></li> 19 </ul> 20 </div> 21 <div class="modal-footer"> 22 <%= f.submit "完了", class: "btn" %> 23 </div> 24<% end %>

ユーザーモデル
バリデーションの設定で、英数字のみに限定
user.rb

ruby

1#friendly_url 2 include FriendlyId 3 friendly_id :friendly_url 4 5 validates :friendly_url, length: { in: 3..20 }, 6  uniqueness: true, #一意性 7  format: { with: /\A[\w@-]*[A-Za-z][\w@-]*\z/ }, #英数字のみ 8  on: :friendly_url_user #登録時に入力必要なし

friendly_idに関するmigrationファイル

ruby

1class AddFriendlyUrlToUsers < ActiveRecord::Migration 2 def change 3 add_column :users, :friendly_url, :string 4 5 add_index :users, :friendly_url, :unique => true 6 end 7end

コントローラー該当部
user_controller.rb

ruby

1def update 2 @user = User.friendly.find(params[:id]) 3 @user.update(update_params) 4 if @user.valid? 5 flash[:notice] = "更新しました" 6 if @user.friendly_url 7 redirect_to "/#{@user.friendly_url}" 8 else 9 redirect_to :user and return 10 end 11 else 12 if @user.friendly_url? 13 render :error 14 else 15 render :error 16 end 17 end 18 end 19 20 private 21 22 def update_params 23 params.require(:user).permit(:nickname, :password, :password_confirmation, :current_password, :avatar, :description, :twitter, :instagram, :friendly_url) 24 end 25 26 def correct_user 27 user = User.friendly.find(params[:id]) 28 if current_user != user 29 redirect_to root_path 30 end 31 end

試したこと

実際に、データベースに保存されてしまっているため、モデルのみだけではなくデータベースにもバリデーションをかけるのが必要なのでは...?と考えています。
しかし、送信後Railsのエラー画面になるのではなく、エラーメッセージを表示するもしくは、指定したページに飛ばすようにしたいと考えています。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

on: :friendly_url_user #登録時に入力必要なし

にてバリデート実行タイミングを明示しているため

ruby

1 @user.update(update_params) 2 if @user.valid?

では、検証を実行していません。(むしろエラーになっているのが不思議です。)

onにより、検証の実行を問うよりもallow_nilallow_blankにて空白や無入力を許可した方がよいでしょう

投稿2019/04/19 22:10

asm

総合スコア15147

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

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

Romay

2019/04/20 00:51

回答ありがとうございます。ユーザー登録時には、friendly_urlを設定しない仕様のため'on'を使っていたのですが、空白や無入力を許可した状態で常にこのバリデーションをかけるのが良いということでしょうか。
asm

2019/04/20 01:38

「登録時以外は検証する。」というのを徹底するのならonによって制御してもいいですが 実際、提示されたupdateでは検証されていないようです。 「登録時には入力しない」と「未入力を許可」の間にある違いが無視できるのならば (つまりは、未入力の更新や登録→解除を許可できる)のならば、そちらの方がよいでしょう。
Romay

2019/04/23 06:18

allow_nilで処理することにしました。回答いただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問