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

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

ただいまの
回答率

90.38%

  • Ruby

    9912questions

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

  • Ruby on Rails

    9324questions

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

  • Ruby on Rails 4

    2561questions

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

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 417

s_diff

score 97

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

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

#controller

  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)
    @page = 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>
#common.js

  window.addEventListener('DOMContentLoaded', function(e){
    document.querySelector('#number-display-form').addEventListener('submit',function(e){
      var t=e.target;
      e.preventDefault();
      var url=t.getAttribute('action')+t.querySelector('select').value;
      location.href=url;
    });
  });


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

routes.rb
get 'products/index/:per' => 'products#index_page', as: 'products_index_page'
  def index_page
    @page = params[:per]
    products = @q.result(distinct: true).enable_products.order( created_at: :desc )
    @product_cnts = products.count
    @products = products.page(params[:page]).per(params[:per])
    @area = Area.find_by(id: @q.area_id_eq)
    @areas = Area.all
    render("index")
  end

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

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

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

<!-- _numberdisplay.html.erb -->
<p>表示件数:</p>
<%= f.select :per_page, [['9件', 9], ['27件', 27], ['54', 54件]], selected: 9 %>
<%= f.submit '切替' %>
<!-- index.html.erb -->
<!-- search_formでpartialも囲うことで、partialからのsubmitを可能にします -->
<%= search_form_for @q, url: products_path do |f| %>
  <div class ="search_zone" >
    <%= f.search_field :name_or_address_or_station_or_area_id_cont %>
    <%= f.submit "さがす", class: "searchbtn" %>

    <!-- partialはこちらに、レイアウトの問題があればcssで調整が良いかと -->
    <%= render :partial => "numberdisplay", :locals => { f: f} %>
  </div>
<% end %>

<div id="products-box">
  <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 %>
  <%= paginate(@products) %>
</div>

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

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

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

<!-- index.html.erb -->
<%= search_form_for @q, url: products_path do |f| %>
  <div class ="search_zone" >
    <%= f.search_field :name_or_address_or_station_or_area_id_cont %>
    <%= f.submit "さがす", class: "searchbtn" %>  
  </div>
<% 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 %>
  <%= paginate(@products) %>
</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/29 21:12 編集

    ただ、これ書いたあとに思ったのですが、
    fieldsetタグを使ったほうが楽かもしれません。
    http://master-html5.blogspot.com/2011/07/formform.html

    キャンセル

  • 2018/10/30 11: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 %>

    最後までご丁寧に教えていただき、本当にありがとうございました!
    おかげさまで開発がとてもはかどり、勉強になりました。
    今後とも宜しくお願いいたします。

    キャンセル

  • 2018/10/30 12:17

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

    キャンセル

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

  • ただいまの回答率 90.38%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Ruby

    9912questions

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

  • Ruby on Rails

    9324questions

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

  • Ruby on Rails 4

    2561questions

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