以前製作していたAJax制御を伴う検索システムに、新規登録画面を修復した所、困った問題が発生しました。
#【使用環境】
- Ruby 2.6 Rails6.1.3
- Virtual Box6.1 CentOS7.4
#発生した問題点
createアクションが被ってしまい、Ajax制御ができなくなりました。
- AjaxはRails-ujsを用いて発火しているが、これによる検索処理がコントローラ内のcreateアクションとなっている。
- 一方で、新規登録を実行した際の処理用アクションもcreateとなっている。
このようにログを確認すると双方ともアクションはcreateになっており、被ってしまっていることがわかります。
log:development.log
1Processing by CitiesController#create as HTML 2 Parameters: {"authenticity_token"=>"[FILTERED]", "city"=>{"base_no"=>"1301", "city_name"=>"東京特別区", "region"=>"関東", "pref_no"=>"13", "population"=>"9620000"}, "commit"=>"Create City"} 3 4Processing by CitiesController#create as JS 5 Parameters: {"q"=>{"pref_no_eq"=>"", "city_name_cont"=>"", "population_gteq"=>"", "population_lteq"=>""}, "commit"=>"Search"} 6Completed 400 Bad Request in 3ms (ActiveRecord: 0.0ms | Allocations: 652)
いちおう、indexアクションに記載している処理をまるごとcreateアクションに書き換えるとAjaxは機能しますが、それだと今度は新規作成ができなくなってしまいます。
実現したいこと
もともとはAjaxはjQuery-ujsで制御してindexアクションに飛ぶようにしていました。その後Rails6になってjquery-ujsでAjax制御するとbootstrapが機能しなくなったので、Rails-ujsで制御するようにしました。ですが、AjaxをRails-ujsで発火するようになったことにより、indexアクションではなくcreateアクションに飛んでしまうようになってしまったので、こっちをcreateアクションではなくindexアクションに飛ばすようにできないでしょうか。あるいは明示的にパラメータを指定して、jsまたはformに対して、任意のアクションに飛ばす制御ができないかご教授お願い致します。
やってみたこと
- formタグにパラメータを付与してみた
- routes.rbに明示的にルーティングを記載してみた
- Rails-ujsのパラメータを明示して、イベントを発火するようにしてみた。
いずれもうまくいかずです。
cities_controller.rb
rb
1class CitiesController < ApplicationController 2 protect_from_forgery :except => [:index,:paginate,:picture] 3 before_action only: [:new, :show, :edit, :update, :destroy, :picture] 4#中略 5 def index 6 query = "select distinct(region) as region from cities group by region order by pref_no" 7 @regions = City.find_by_sql(query) 8 unless params[:q].blank? 9 logger.debug('TR') 10 @q = City.ransack(params[:q]) 11 @q.sorts = 'population desc' if @q.sorts.empty? 12 @cities = @q.result.page(params[:page]).per(10) 13 #コンテナのレンダリング 14 p_pager = render_to_string( 15 partial: 'ajax_pager', 16 locals: { :cities => @cities }, 17 ) 18 if request.xhr? 19 render json:{ 20 container: p_cities, 21 pager: p_pager, 22 } 23 end 24 else 25 @q = City.ransack(params[:q]) 26 @q.sorts = 'population desc' if @q.sorts.empty? 27 @cities = @q.result.page(params[:page]).per(10) 28 end 29 end 30 31 #テーブルデータの新規登録 32 def create 33 @city = City.new(city_params) 34 logger.debug("testtesttestst") 35 respond_to do |format| 36 if @city.save 37 format.html{ redirect_to @city, notice:'City was successfully created.'} 38 format.json{ render :show,status: :created, location: @city } 39 else 40 format.html{ render :new} 41 format.json{ render json: @city.errors, status: :unprocessable_entity } 42 end 43 end 44 end
Ajaxの発火用js
js
1import * as $ from "jquery"; 2import Rails from "@rails/ujs"; 3 4function register_callback(){ 5 jQuery(function(){ 6 let data 7 $("#city-form").each(function(){ 8 $("#ajax-contents").on('change keyup',function(e){ 9 console.log("A") 10 console.log($('#city-form').get(0)) 11 Rails.fire($('#city-form').get(0), 'submit') 12 }) 13 }) 14 $("#city-form").on( 15 "ajax:complete", 16 function(d){ 17 //console.log("BO") 18 if(d.detail[0].status == 200){ 19 data = d.detail[0].responseText 20 data = $.parseJSON(data) 21 //console.log("KU") 22 $('#ajax-response-wrapper').empty().append(data.container) 23 $('#pager').empty().append(data.pager) 24 } 25 } 26 ) 27 $("#city-form").on("ajax:fail",function(event,data,status,xhr){ 28 alert("fail!") 29 }) 30 }) 31 32 33window.register_callback = register_callback;
編集フォームはこのpartialファイルを用いています。
_form.html.erb
erb
1<%= form_for @city, :html => { :class => "form-horizontal city" } do |f| %> 2 3 <% if @city.errors.any? %> 4 <div id="error_expl" class="panel panel-danger"> 5 <div class="panel-heading"> 6 <h3 class="panel-title"><%= pluralize(@city.errors.count, "error") %> prohibited this city from being saved:</h3> 7 </div> 8 <div class="panel-body"> 9 <ul> 10 <% @city.errors.full_messages.each do |msg| %> 11 <li><%= msg %></li> 12 <% end %> 13 </ul> 14 </div> 15 </div> 16 <% end %> 17 18 <div class="form-group"> 19 <%= f.label :base_no, :class => 'control-label col-lg-2' %> 20 <div class="col-lg-10"> 21 <%= f.text_field :base_no, :class => 'form-control' %> 22 </div> 23 <%=f.error_span(:base_no) %> 24 </div> 25 <div class="form-group"> 26 <%= f.label :city_name, :class => 'control-label col-lg-2' %> 27 <div class="col-lg-10"> 28 <%= f.text_field :city_name, :class => 'form-control' %> 29 </div> 30 <%=f.error_span(:city_name) %> 31 </div> 32 <div class="form-group"> 33 <%= f.label :region, :class => 'control-label col-lg-2' %> 34 <div class="col-lg-10"> 35 <%= f.text_field :region, :class => 'form-control' %> 36 </div> 37 <%=f.error_span(:city_name) %> 38 </div> 39 <div class="form-group"> 40 <%= f.label :pref_no, :class => 'control-label col-lg-2' %> 41 <div class="col-lg-10"> 42 <%= f.text_field :pref_no, :class => 'form-control' %> 43 </div> 44 <%=f.error_span(:pref_no) %> 45 </div> 46 <div class="form-group"> 47 <%= f.label :population, :class => 'control-label col-lg-2' %> 48 <div class="col-lg-10"> 49 <%= f.text_field :population, :class => 'form-control' %> 50 </div> 51 <%=f.error_span(:population) %> 52 </div> 53 <div class="form-group"> 54 <div class="col-lg-offset-2 col-lg-10"> 55 <%= f.submit nil, :class => 'btn btn-primary' %> 56 <%= link_to t('.cancel', :default => t("helpers.links.cancel")), 57 cities_path, :class => 'btn btn-default' %> 58 </div> 59 </div> 60<% end %>
routes.rb
rb
1Rails.application.routes.draw do 2resources :cities 3root to: 'cities#index' 4 post 'cities/index', to: 'cities#index' 5 post 'cities/create', to: 'cities#create' 6 post 'cities/picture', to: 'cities#picture' 7 #post 'cities/index', to: 'cities#index',as: 'cities_index' 8 # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 9end
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/12/27 01:54 編集