#author("2017-06-22T13:17:23+09:00","default:wikiwriter","wikiwriter") &tag(Rails/検証); *目次 [#w60a64b3] #contents *関連ページ [#j1a32407] -[[Rails]] -[[../Bootstrap]]…Bootstrapを使った場合のエラーメッセージの表示方法などについて。 *参考情報 [#bd325948] *概容 [#q53af642] **validatesとvalidates...ofの違い [#r2bdad94] -例えばvalidates_uniqueness_ofとvalidates :uniquenessの違い。 -[[validates vs validates..._of ... · Issue #571 · bbatsov/ruby-style-guide:https://github.com/bbatsov/ruby-style-guide/issues/571]]によると、validatesのほうが複数の検証を一気にかけて便利らしい。 *一般的なCRUD処理時の検証の流れ [#o19460f3] -モデルクラスにvalidatesメソッドの追加 #pre{{ class Item < ActiveRecord::Base validates :title, presence: true end }} -controllerクラスでの検証 -scaffoldのデフォルト実装でも検証は行われる。 #pre{{ def create @item = Item.new(item_params) respond_to do |format| if @item.save format.html { redirect_to @item, notice: 'Item was successfully created.' } format.json { render :show, status: :created, location: @item } else format.html { render :new } format.json { render json: @item.errors, status: :unprocessable_entity } end end end }} -ビューでは以下のようにエラーメッセージを表示する(もう少し分かりやすく表示する必要あり) #pre{{ <%= form_for(@item) do |f| %> <% if @item.errors.any? %> <div id="error_explanation"> <h2>エラーが発生しました :</h2> <ul> <% @item.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :title %><br> <%= f.text_field :title %> </div> <div class="field"> <%= f.label :content %><br> <%= f.text_area :content %> </div> <div class="actions"> <%= f.submit %> </div> <% end %> }} *特別な検証 [#x54b3ed1] **URLを検証する [#ude9b880] -[[perfectline/validates_url:https://github.com/perfectline/validates_url]] -[[Rails - gem validates_url 使ってみた - Qiita:http://qiita.com/mtsuge/items/366f44261c63b61db221]] -Gemfileに追加 gem "validate_url" -モデルで検証 #pre{{ class User < ActiveRecord::Base validates :homepage, url: { allow_blank: true } end }} *エラーメッセージの表示 [#f28a9229] **flash.nowとflashの違い [#i86c54f2] -[[[Rails] flash.now[:notice]とflash[:notice]の違い − 拝啓、シーシュポス:http://trwtnb.blogspot.jp/2009/11/rubyrailsflashnownoticeflashnotice.html]]によると、flash.nowはrenderでメッセージを表示したい場合、flashはredirectで表示したい場合。 -flash.nowに設定されたメッセージを列挙する方法はないが(flash.now.eachはできない)、flash[:notice]で、flash.now[:each」を表示することはできる(すなわちflash.eachを使うしかない)。[[Rails Flash.now not working - Stack Overflow:http://stackoverflow.com/questions/7133392/rails-flash-now-not-working]] ** Bootstrap3を使う場合 [#k12b3eaf] [[../Bootstrap]]を参照のこと。 *検証後入力値が再表示される仕組み [#c4073d67] -scaffoldで作成したコントローラーは以下のようになっている。 #pre{{ # GET /items/new def new @item = Item.new end # GET /items/1/edit def edit end # POST /items # POST /items.json def create @item = Item.new(item_params) respond_to do |format| if @item.save format.html { redirect_to @item, notice: 'Item was successfully created.' } format.json { render :show, status: :created, location: @item } else format.html { render :new } format.json { render json: @item.errors, status: :unprocessable_entity } end end end # PATCH/PUT /items/1 # PATCH/PUT /items/1.json def update respond_to do |format| if @item.update(item_params) format.html { redirect_to @item, notice: 'Item was successfully updated.' } format.json { render :show, status: :ok, location: @item } else format.html { render :edit } format.json { render json: @item.errors, status: :unprocessable_entity } end end end }} -create、updateが登録後の処理となる。成功した場合はredirectして再表示、エラーの場合は入力値が設定された@itemを使ってnewやeditをrenderするので、入力値が再表示される。 -ただし、@itemはよいのだが、値選択用のリストボックスなどの準備をnewで行っている場合それらの準備も行わないといけない(newと同様の処理)。 -また、検証失敗後URLは以下のように変わる --追加初期表示時のURL: 「http://localhost:3000/items/new」 --追加失敗時のURL: 「http://localhost:3000/items」(実際は追加初期表示時の見た目のまま) --更新初期表示のURL:「http://localhost:3000/items/3/edit」 --更新失敗後のURL: 「http://localhost:3000/items/3」(実際は更新初期表示の見た目のまま) *Active Recordの検証機能 [#e98d3c23] **値の存在チェック [#q34e8f70] -validatesで、presenceを指定 #pre{{ class Person < ActiveRecord::Base validates :name, presence: true end Person.create(name: "John Doe").valid? # => true Person.create(name: nil).valid? # => false }} *PENDING [#nedcc2a6] **テーブル形式の入力フォームでの検証方法は? [#tb678893] -fields_forを使ってテーブル形式で複数データを一気に登録できるフォームの場合、エラーが発生したフィールドをハイライト表示する方法がわからない。 -errors.addの第1引数はフィールドのシンボルだが、fields_forの場合はどうなる?