#author("2016-04-21T16:37:52+09:00","default:wikiwriter","wikiwriter") &tag(Rails/フォーム); *目次 [#zc5cb8b4] #contents *関連ページ [#tbe1b391] *参考情報 [#v2e8a01d] *Tips [#r6205d0d] **フォーム内のボタンをsubmit以外にする [#t773b6f7] -[[RailsのForm内のbuttonでsubmit以外のことをさせたい(link_to的なこと) - Qiita:http://qiita.com/t_oginogin/items/b682f664ce8244a7c2bd]] -結局link_toの中にbutton_tagを書くしかない? #pre{{ <%= link_to (button_tag "ボタン", type: 'button'), { controller: :books, action: :new } %> }} **データの保存時に空白をnullに変換 [#sb3131d6] -[[mysql - Rails: Force empty string to NULL in the database - Stack Overflow:http://stackoverflow.com/questions/7202319/rails-force-empty-string-to-null-in-the-database]]によると簡単に実行する方法はない? -[[rubiety/nilify_blanks:https://github.com/rubiety/nilify_blanks]]…nifty blanksというgemがあるらしいけど。 **複数Submitボタンが存在するForm [#xd43d26a] -ビュー側 #pre{{ <%= form_tag(operate_url) do %> <%= submit_tag('移動')%> <%= submit_tag('削除', {name: 'delete'})%> <% end %> }} -コントローラー側 #pre{{ if params[:delete] #削除処理 redirect_to(folder_path(@folder), notice: "削除しました") else #通常処理 redirect_to(folder_path(@folder), notice: "移動しました") end }} **2重保存を防ぐ [#d65bc4c1] ***double submit protectionを使う [#h97eedea] -Submitを無効化するのではなく、戻る=>保存の2重登録を防ぐ方法。 --[[herval/double_submit_protection:https://github.com/herval/double_submit_protection]] --[[実録!Railsのはまりポイント10選:http://www.slideshare.net/drecom/edgerails2]] --[[browser - Rails: Prevent duplicate inserts due to pressing back button and save again - Stack Overflow:http://stackoverflow.com/questions/4657758/rails-prevent-duplicate-inserts-due-to-pressing-back-button-and-save-again]] -全部同じアイデアでセッションにトークンを保存して、保存時に確認する処理を入れる。しかしかなり古いし、最近の情報はあまり見つからない。より良い方法があるか確認する。 -ちなみにRedmineでも戻る、保存で連続作成できてしまう。何もしないのが定石? ***ハッシュ値を計算して2重登録を防ぐ方法 [#aa8c6cb2] -[[Prevent double data submission in Rails 3 - hibbard.eu:http://hibbard.eu/prevent-double-data-submission-in-rails-3/]]にて提唱されている方法。 -JavaScriptでボタンを無効化した上直前に登録されたデータとハッシュ値の比較を行うことで防ぐ。 -モデルに以下を追加 #pre{{ def make_hash res = [] columns_to_skip = ["created_at", "updated_at", "hash"] for column in Applicant.content_columns next if columns_to_skip.include?(column.name) or self[column.name].nil? or self[column.name].blank? res << self[column.name] end res.hash.to_s end }} -コントローラーに以下を追加。 #pre{{ def create @applicant = Applicant.new(params[:applicant]) a = Applicant.last @previous_applicant_hash = (a.nil?)? 0 : a.applicant_hash if @applicant.valid? unless @applicant.applicant_hash == @previous_applicant_hash @applicant.save ApplicantMailer.admin_notification(@applicant).deliver ApplicantMailer.application_confirmation(@applicant).deliver end redirect_to :action => "success" else render action: "new" end end }} ***Redisを使う [#s049eb5c] -redisを使う #pre{{ Redis.current.lock("#{current_user.id}.action_name") do # Some code end }} ***PHPの方法 [#cd9b087c] -[[PHPでの二重送信対策が、効いていない?(追記あり) - Qiita:http://qiita.com/cufh/items/e04f544ff3f68ff4a883]]などなど。チケット、トークンなどで検索。