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

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

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

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

Ruby on Rails

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

Q&A

1回答

347閲覧

1対多で関連づけられたモデルを指定して一覧ページを表示する方法が知りたい。

shutheonetokyo

総合スコア0

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2022/01/16 09:25

質問失礼いたします。

現在、Railsポートフォリオとしてアパレル店舗の口コミアプリを作成しているのですが、やりたいことがうまくいかず、調べても出てこないので質問させていただきます。

やりたいこと

トップページ内の「エリアから探す」画面から、選択したエリアのみのショップだけを表示したい。
例えば「原宿」を選択すると、原宿で登録したエリアに関連づけられたショップ一覧ページのみを表示したい。

これまでの過程

ShopモデルとAreaモデルを作成し、それぞれを1対多で関連付ける。

app/models/shop.rb

1class Shop < ApplicationRecord 2 mount_uploader :image, ImageUploader 3 4 belongs_to :area 5end

app/models/area.rb

1class Area < ApplicationRecord 2 has_many :shops 3end

管理者画面にてエリアとショップをそれぞれ作成し、ショップを新規登録する際にエリアも指定できるようにした。
例えば「ユニクロ 新宿西口店」を新たに作成するときに、エリアを「新宿」に指定して作成。

トップページにはショップを調べる方法として「①検索フォーム、②エリアから探す、③ジャンルから探す、④ブランドから探す」の4つの項目を用意する予定。現在②でうまくいかず困っている。
トップページのapp/views/static_pages/home.html.erbに登録したエリアを全て表示することはできたが、どのリンクを開いても全てのショップが表示され、指定したエリアの中でのショップ一覧を表示することができない。

試したこと

app/controllers/shops_controller.rbにて、@shopにエリアを指定するパラメーターを記述しようとしたが、どう書けばいいか分からない。
ransackを使って条件を指定して検索できそうなので、調べてみたが、それっぽい記事を見つけることができなかった。

app/controllers/static_pages_controller.rb

1class StaticPagesController < ApplicationController 2 3 PER_PAGE = 10 4 5 def home 6 @q = Shop.ransack(params[:q]) 7 @shops = @q.result.page(params[:page]).per(PER_PAGE) 8 @areas = Area.all 9 end 10 11end

app/views/static_pages/home.html.erb

1<!-- static_pages area --> 2 3<div class="area"> 4 <h1>エリアから探す</h1> 5 <div class="card ml-3" style="width: 90%"> 6 <div class="card-body"> 7 <h1>東京</h1> 8 <p class="card-text"> 9 <% @areas.each do |area| %> 10 <%= link_to area.name, shops_path(?), class: 'btn btn-outline-secondary btn-lg m-3' %> 11 <% end %> 12 </p> 13 </div> 14 </div> 15</div>

app/controllers/shops_controller.rb

1class ShopsController < ApplicationController 2 3 PER_PAGE = 10 4 5 def index 6 @q = Shop.ransack(params[:q]) 7 @shops = @q.result.page(params[:page]).per(PER_PAGE) 8 @areas = Area.find(params(?)) 9 end 10 11 def show 12 @shop = Shop.find(params[:id]) 13 end 14end

トップページのリンク先の一覧ページは以下の通りです。

app/views/shops/index.html.erb

1<div class="shop-list"> 2 <% if @shops.present? %> 3 <p><%= @shops.length%>件ヒットしました。</p> 4 <% @shops.each do |shop| %> 5 <%= link_to shop do %> 6 <p><%= shop.name %></p> 7 <p><%= shop.address %></p> 8 <p><%= shop.area.name %></p> 9 <% end %> 10 <% end %> 11 <% else %> 12 <p>検索結果は見つかりませんでした。</p> 13 <% end %> 14</div> 15 16<%= paginate @shops %>

結論

(?)の箇所にエリアを関連づけたショップだけを表示するためのコードが分かれば解決すると考えてみたのでですが、どういう風に書けばよいか教えて頂きたいです。

そもそも根本的な方法が違っているかどうかも不安な知識レベルなので、より効率的な表示方法を教えていただければありがたく思います。

また、shopsテーブルとareasテーブル、genresテーブル、brandsテーブルの関連付け(1対多)の状態のまま作成を進めていいのかも不安なので、もし間違っていたらご指摘していただくとなおありがたく思います。現在のER図を添付しておきます。

イメージ説明

念の為、現在のshopsとareasのrails routesの結果も添付しておきます。

shops GET /shops(.:format) shops#index POST /shops(.:format) shops#create new_shop GET /shops/new(.:format) shops#new edit_shop GET /shops/:id/edit(.:format) shops#edit shop GET /shops/:id(.:format) shops#show PATCH /shops/:id(.:format) shops#update PUT /shops/:id(.:format) shops#update DELETE /shops/:id(.:format) shops#destroy areas GET /areas(.:format) areas#index POST /areas(.:format) areas#create new_area GET /areas/new(.:format) areas#new edit_area GET /areas/:id/edit(.:format) areas#edit area GET /areas/:id(.:format) areas#show PATCH /areas/:id(.:format) areas#update PUT /areas/:id(.:format) areas#update DELETE /areas/:id(.:format) areas#destroy

長文、かつ分かりにくい質問となってしまい申し訳ありませんが、よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ShopのControllerにおいて、現在のコードでは、area がどこであれ、それとは無関係に @shops が定義されているので、それが問題になっています。
だから、同コードにおいて、そのエリアに限った店オブジェクトのrelation (配列)である @shops を用意する必要があります。

ruby

1# app/controllers/shops_controller.rb 2class ShopsController < ApplicationController 3 4 def index 5 area = Area.find(params[:area_id]) 6 if area 7 @shops = area.shops # ← 指定したareaのshopsだけ。Modelでの一対多の設定利用。 8 else 9 raise "そんな地域は存在しません" # ← 保険。Viewが正しく設定されていれば、ここに来ることはない 10 end 11 end 12

あとは、このページに遷移する前のページ(検索ページなり、トップページでない)にて、「送信」した時に、該当パラメーター(上の例であれば、area_id という名前で、Areaモデルの該当primary IDを送ると仮定しています)が送られるように、その検索ページのViewを設定することになります。

投稿2022/01/16 17:33

MasaSakano

総合スコア188

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

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

shutheonetokyo

2022/01/17 06:20

ご回答していただきありがとうございます。 早速教えていただいた通りに、app/controllers/shops_controller.rbにて、エリア限定に配列するコードにしました。 View側なのですが、app/views/static_pages/home.html.erb内の <%= link_to area.name, shops_path(?), class: 'btn btn-outline-secondary btn-lg m-3' %> この?に、該当のパラメーターが送られるようにshops_path(area.id)やshops_path(area_id)など、色々入力して試してみたのですがうまくいきませんでした。 これに関しても調べても出てこなかったので、教えていただけると幸いです。 初歩的なところで申し訳ありませんが、よろしくお願いいたします。
MasaSakano

2022/01/19 23:33

それはこの質問に対する本来の回答とは別の軸の質問になりましょう。 端的には、「ある指定パラメーターを送るような(Homeの) viewをどのように記述すればよいか」という質問ですね。 その点に絞った質問を(状況を単純化して新たに書いて)独立に立てることをお勧めします。
shutheonetokyo

2022/01/21 05:36

かしこまりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問