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

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

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

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

Ruby

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Q&A

解決済

1回答

1692閲覧

Railsで「ユーザーの保存しているレストランを検索する」ようなメソッドはどのモデルに記述すべきか

tomohiroo

総合スコア19

Ruby on Rails 5

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

Ruby

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

0グッド

0クリップ

投稿2018/10/27 08:27

編集2018/10/27 08:34

Ruby on Railsで飲食店の情報を管理するようなサービスを作っています。

話に関係するモデルは、以下の写真のように、User, Restaurant, Clip, Station, Category, Clip_category, Boardと言ったところです。
ER図

この中で、保存したレストランを検索するメソッドを作っています。

controllerで

station = Station.search params[:query] board = Board.search params[:query]

だいたい上のように各モデルへの操作を書いています。

ここで質問が2つあるのですが、

  1. current_userのクリップ(保存したレストラン)一覧を取得するようなモデルを跨ぐようなメソッドをモデル層に記述したいときはuser.rbやclip.rb、restaurant.rbなど、どのモデルに、また、クラスメソッド、もしくはインスタンスメソッドのどちらで作るべきなのでしょうか?

現状は、
Clip.search(params[:query], current_user.id)のようにクリップクラスからメソッドを生やすか
current_user.search_clips(params[:query])のようにユーザーのインスタンスメソッドを作るか
の2つで迷い、後者を採用しています。

  1. 今は、あるモデルについて検索するメソッドをモデルに書き、それをcontrollerで使っていますが、そもそもClip.get_with_queryのようなメソッドを作り、現在controllerで行っているような処理を全てmodelで行ってしまった方がいいのでしょうか?

controllerとmodelをどう使い分けるべきかがよくつかめていません。

以上2点です。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

まず、Railsガイドの「Active Record の関連付け (アソシエーション)」を読んでみてください。
https://railsguides.jp/association_basics.html

User、Clip、Restaurantの関係は、ここで出てくる「2.4 has_many :through関連付け」のPhysician、Appointment、Patientに相当すると思います。

そのため、

ruby

1 2class User < ApplicationRecord 3 has_many :clips 4 has_many :restaurants, through: :clips 5end 6 7class Clip < ApplicationRecord 8 belongs_to :users 9 belongs_to :restaurants 10end

といったようになっていれば、current_user.restaurantsでクリップしたレストランが取得できるかと思います。

2つ目の質問ですが、モデルを検索するメソッドはモデルにあった方がよいですが、コントローラーで使いたい処理はまずはコントローラーに置いてもよいでしょう。ただ、他の箇所からも同様の処理を行いたくなった場合は、モデルのメソッドにリファクタリングした方がよいです。
最初から一発で正解を求めるのは難しいので、多少の回り道は覚悟した上で、少しずつアプリを育てていくつもりで書いていく方が現実的かもしれません。

投稿2018/11/02 14:58

takahashim

総合スコア1877

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

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

tomohiroo

2018/11/02 15:31

回答ありがとうございます!! 確かに、徐々にアプリを育てて行く意識は大切かもしれません、ご指摘ありがとうございます。 1つ目の質問についてなのですが、現在、リレーションはちゃんと敷いており、current_user.restaurantsでもuserがクリップしたレストランを全件取得できるのですが、全件取得ではなく、queryや、ジャンル(「ラーメン」、「イタリアン」など)など色々な条件で絞り込むようなメソッドについては、どのモデルに実装すべきか、ということで悩んでおります。
takahashim

2018/11/02 15:44 編集

なるほど、アソシエーションは設定されてるんですね。 件数が多くなければ全件取得してから絞り込みを行ってもいいかと思いますが、もう少しDBへのクエリに処理を寄せたいのであれば、「そのメソッドが返して欲しいオブジェクトのクラス」に置く、というのが分かりやすいかもしれません。 例えば「current_userの、何かの条件で絞り込んだクリップ(保存したレストラン)一覧を取得する」といった場合、返してほしいのはクリップではなくレストラン(の一覧)だと思うので、Restaurantのメソッドとして実装することにして、引数にユーザや絞り込み条件を指定するとスッキリするかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問