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

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

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

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

Ruby on Rails

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

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

1348閲覧

【Ruby On Rails】検索結果を踏まえた表示件数切り替え機能を実装したい

s_diff

総合スコア107

Ruby

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

Ruby on Rails

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

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

0クリップ

投稿2018/10/26 01:47

一覧ページで検索機能と表示件数切替機能を実装したのですが、
現在の状態だと検索を行った後に表示切替を行うと、検索結果がリセットされてしまいます。

検索の結果を保持したままで表示切替を行うにはどうすればいいのかを知りたいです。

ruby

1#controller 2 3 def index 4 @area = Area.find_by(id: @q.area_id_eq) 5 products = @q.result(distinct: true).enable_products.order( created_at: :desc ) 6 @product_cnts = products.count 7 @products = products.page(params[:page]).per(9) 8 @page = 9 9 end
<!-- index.html.erb --> <div class ="search_zone" > <%= search_form_for @q, url: products_path do |f| %> <%= f.search_field :name_or_address_or_station_or_area_id_cont %> <%= f.submit "さがす", class: "searchbtn" %> <% end %> </div> <div id="products-box"> <%= render :partial => "numberdisplay", :locals => { action: "/products/index/"} %> <!-- 表示件数切り替え --> <h2>画像一覧:<%= @product_cnts %></span>&nbsp;件</h2> <%= link_to product_path(id: product.id) do %> <%= render :partial => "productbox", :locals => { img_class: "", product: product, building_name_class: "", current_mosaic: ""} %> <% end %> <%= paginate(@products) %> </div>

上のindex.html.erb内search_zoneで検索した結果を保持した上で表示件数切替を行いたいのですが、
現状では表示件数切替を行うと、検索結果がリセットされてしまいます。

パーシャルのnumberdisplayは以下です。

<!-- _numberdisplay.html.erb --> <form action=<%= action %> method="get" id="number-display-form" class="number-display-form"> <p>表示件数:</p> <select id="number" class="number" required> <option value="" disabled="disabled" selected> 選択してください </option> <option value="9">9件</option> <option value="27">27件</option> <option value="54">54件</option> </select> <input type='submit' value='切替'> </form>

javascript

1#common.js 2 3 window.addEventListener('DOMContentLoaded', function(e){ 4 document.querySelector('#number-display-form').addEventListener('submit',function(e){ 5 var t=e.target; 6 e.preventDefault(); 7 var url=t.getAttribute('action')+t.querySelector('select').value; 8 location.href=url; 9 }); 10 });

ここから別のコントローラに行って先程のindex.html.erbをrenderします。

ruby

1routes.rb 2get 'products/index/:per' => 'products#index_page', as: 'products_index_page'

ruby

1 2 def index_page 3 @page = params[:per] 4 products = @q.result(distinct: true).enable_products.order( created_at: :desc ) 5 @product_cnts = products.count 6 @products = products.page(params[:page]).per(params[:per]) 7 @area = Area.find_by(id: @q.area_id_eq) 8 @areas = Area.all 9 render("index") 10 end

長くなってしまって大変申し訳ありません。
この流れの中で、どのように検索結果を渡せばよいのでしょうか?

なにかご教示していただけることがあれば、何卒よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

'切替'によるsubmit時には検索パラメーター(:name_or_address_or_station_or_area_id_cont)が渡されていないためと思います。

'切替'も'さがす'と同じリクエスト先になりますよね?
ですから、formは一つでいいかと思います。イメージは以下

html

1<!-- _numberdisplay.html.erb --> 2<p>表示件数:</p> 3<%= f.select :per_page, [['9件', 9], ['27件', 27], ['54', 54件]], selected: 9 %> 4<%= f.submit '切替' %>

html

1<!-- index.html.erb --> 2<!-- search_formでpartialも囲うことで、partialからのsubmitを可能にします --> 3<%= search_form_for @q, url: products_path do |f| %> 4 <div class ="search_zone" > 5 <%= f.search_field :name_or_address_or_station_or_area_id_cont %> 6 <%= f.submit "さがす", class: "searchbtn" %> 7 8 <!-- partialはこちらに、レイアウトの問題があればcssで調整が良いかと --> 9 <%= render :partial => "numberdisplay", :locals => { f: f} %> 10 </div> 11<% end %> 12 13<div id="products-box"> 14 <h2>画像一覧:<span><%= @product_cnts %></span>&nbsp;</h2> 15 <%= link_to product_path(id: product.id) do %> 16 <%= render :partial => "productbox", :locals => { img_class: "", product: product, building_name_class: "", current_mosaic: ""} %> 17 <% end %> 18 <%= paginate(@products) %> 19</div>

また、いくつか蛇足ですが。

  • おそらく、ransackですよね?その辺の情報も書いてあると、回答しやすいですね。
  • numberdisplayはpartial化しなくても良いんじゃないかと思います。他で使わなければね。
  • controllerの情報が不足してそうですね(@qってなにとか。before_actionとかでセットしてるんじゃないかな?)。フルで貼れれば、そのほうがいいと思いますよ。
  • 表示件数をper_pageパラメーターで渡してますが、これをcontroller側で読み取って処理する必要があります。わからなかったらまた聞いてください。
  • javascriptによる送信ロジックはカスタマイズしすぎな気がします。(今回は不要なんじゃないかと思いますが)。ここまでやると、完全にrailを踏み外しているパターンですね。Ajaxをしたいならこのあたり読んでみましょう。
  • 好みによりますが、生のhtmlタグとrailsのhelperで生成されるタグとが入り乱れてて読みづらいですね(たとえばf.submitとinput type = submitタグとか)。可読性のためにもhelper側に統一したほうがいいと思います。

<追記>
以下コメントを受けての追記です。
formを検索フォームとまったく別にするパターンになります

html

1<!-- index.html.erb --> 2<%= search_form_for @q, url: products_path do |f| %> 3 <div class ="search_zone" > 4 <%= f.search_field :name_or_address_or_station_or_area_id_cont %> 5 <%= f.submit "さがす", class: "searchbtn" %> 6 </div> 7<% end %> 8 9<div id="products-box"> 10 <!-- partialにqを渡すことで、partialからのsubmitを可能にします --> 11 <%= render :partial => "numberdisplay", :locals => { q: @q } %> 12 <h2>画像一覧:<span><%= @product_cnts %></span>&nbsp;</h2> 13 <%= link_to product_path(id: product.id) do %> 14 <%= render :partial => "productbox", :locals => { img_class: "", product: product, building_name_class: "", current_mosaic: ""} %> 15 <% end %> 16 <%= paginate(@products) %> 17</div>
<!-- _numberdisplay.html.erb --> <%= search_form_for q, url: products_path do |f| %> <p>表示件数:</p> <!-- hiddenでパラメーターをセット --> <%= f.hidden_field :name_or_address_or_station_or_area_id_cont %> <%= f.select :per_page, [['9件', 9], ['27件', 27], ['54', 54件]], selected: 9 %> <%= f.submit '切替' %> <% end %>

投稿2018/10/26 09:15

編集2018/10/29 12:05
h_daido

総合スコア824

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

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

s_diff

2018/10/29 05:57

返信が遅くなってしまい申し訳ありません。 ご丁寧な回答、ありがとうございます! おっしゃる通りにすると、簡単におもったような実装ができました。 ただ、一つ問題がでてきました。 name_or_address_or_station_or_area_id_contのsearch_formをヘッダーに入れているので、 一覧ページで表示させる表示切替のコードをsearch_formの中に入れることができません。 ヘッダーに無理やり入れても表示させることはできるのですが、 当たり前ですが一覧ページ以外でも表示件数切替が表示されてしまいます。
s_diff

2018/10/29 05:58

またまた説明不足で大変申し訳ないのですが、 この場合なにか対処法があるのでしょうか?
h_daido

2018/10/29 08:14

基本的には、products_pathに対して必要なパラメーターを渡してあげればちゃんと動くはずです。 そのためには、 a. 1つのフォームにまとめてしまう b. 各フォームにちゃんとパラメーターをセットしてあげる のどちらかの実装になります。 最初に提案したのはa.のパターンですね。 レイアウトが分割されることが多いのであれば、b.のパターンでも良いかもしれません。 回答を更新したのでみてもらえればと思います。 (検証する環境がすぐに用意できないので動作確認してないです。。たぶん動くとはおもいますが...。)
s_diff

2018/10/29 09:07 編集

お忙しい中、返信ありがとうございます。 追記の通り実装しましたが、コントローラ内のコードがうまくできてないせいなのか、 検索フォームで検索した後に表示件数を切り替えると、検索したワードがリセットされてしまうようになりました。 def index  @area = Area.find_by(id: @q.area_id_eq)  products = @q.result(distinct: true).enable_products.order( created_at: :desc )   @product_cnts = products.count   @products = products.page(params[:page]).per(9)   p "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"   p params[:q]   p "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" end コントローラに通らなくなったので 上のようにとりあえずper(9)にもどしてrailsサーバーのログを見たところ、 検索したときには、{"building_name_or_address_or_station_or_area_id_cont"=>"福岡県福岡市中央区"} 表示件数を切り替えたときには、{"per_page"=>"27"} のように返されます。 片方を変えてももう片方が保持されたままにするにはどうしたら良いのでしょうか?
h_daido

2018/10/29 12:10

すいません、一番重要なのをわすれてました。 パーシャル側のソースを変更したのでみてみてください。 (例のとおり動作確認してないので、書き方とか微妙にちがうかもしれないです。) 要するにやりたいこととしては、パーシャル側からのsubmitでも"name_or_address_or_station_or_area_id_cont"パラメーターを渡してあげることです。
s_diff

2018/10/30 02:22

f.hiddenでパラメータを渡したところうまくできました。 fieldsetとformを使う方法もとても便利ですね。これから使っていきたいと思います。 以下のような実装で、検索結果を保持した表示切り替え機能が完成しました。 #コントローラ def index @area = Area.find_by(id: @q.area_id_eq) products = @q.result(distinct: true).order( created_at: :desc ) @products = products.page(params[:page]).per(params[:q][:per_page]) end #ビュー <div id="products-box"> <!-- partialにqを渡すことで、partialからのsubmitを可能にする --> <%= render :partial => "numberdisplay", :locals => { q: @q } %>  <h2>画像一覧:<span><%= @product_cnts %></span>&nbsp;件</h2> <%= link_to product_path(id: product.id) do %> <%= render :partial => "productbox", :locals => { img_class: "", product: product, building_name_class: "", current_mosaic: ""} %> <% end %> </div> #_numberdisplay <%= search_form_for q, url: products_path do |f| %> <p>表示件数:<%= @per_page.present? ? @per_page : "9" %></p> <!-- hiddenでパラメーターをセット --> <%= f.hidden_field :building_name_or_address_or_station_or_area_id_cont %> <%= f.hidden_field :area_id_eq %> <%= f.select :per_page, [['9件', 9], ['27件', 27], ['54件', 54]], selected: 9 %> <%= f.submit '切替' %> <% end %> 最後までご丁寧に教えていただき、本当にありがとうございました! おかげさまで開発がとてもはかどり、勉強になりました。 今後とも宜しくお願いいたします。
h_daido

2018/10/30 03:17

ナイストライですね! 微力ですが、お役に立てたらならなによりです<^^>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問