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

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

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

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Active Record

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

Q&A

解決済

2回答

384閲覧

関連モデルを含めたwhere検索について

IRIESS

総合スコア45

Ruby on Rails 6

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Active Record

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

0グッド

0クリップ

投稿2022/04/05 06:03

現在Railsを勉強中のものです。

Rate(評価)モデルから、userが投稿した特定のhostへの評価一覧を検索して取得したいと思っています。

ruby

1class Rate < ApplicationRecord 2 belongs_to :agreement 3 has_one :user, through: :agreement 4 has_one :host, through: :agreement 5 6class Agreement < ApplicationRecord 7 belongs_to :user 8 belongs_to :host 9 has_one :rates 10end 11 12class Host < ApplicationRecord 13 has_many :agreements, dependent: :destroy 14 has_many :rates, through: :agreements 15end 16 17class User < ApplicationRecord 18 has_many :agreements, dependent: :destroy 19 has_many :rates, through: :agreements 20end

恥ずかしながら私が調べながら書いてみたのは以下のような感じです

ruby

1 def show 2 host = Host.find_by(myid: params[:id]) 3 rates = Rate.left_joins(:agreement).includes(agreement: :user).where(:agreement => {host_id: host.id}) 4 5 render rates.as_json( 6 only: %i[id star comment created_at], 7 include: { 8 agreement: { 9 only: [], 10 include: { 11 user: { 12 only: %i[name age] 13 } 14 } 15 } 16 } 17 ) 18 end 19

left_joinsで関連モデルを含めた検索を可能にして、
includesで必要な情報(関連しているagreement.userのname, age等)を取得するためのN + 1対策
whereで関連しているagreementのhost_idがパラメータから事前に検索しておいたhostのidに一致しているものを検索
というイメージでかきました。

しかしこれでは

ruby

1Mysql2::Error: Unknown column 'agreement.host_id' in 'where clause'

うまく関連モデルを紐づけられていないのでしょうか。

先輩エンジニアの皆様ご教授よろしくお願い致します。

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

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

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

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

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

guest

回答2

0

model を直したほうがよさげです。
class Agreement < ApplicationRecord の has_one :rates をやめ、rate は class Agreement の属性にする。

そうしますと
rates = host.agreements
です。
Agreement にrateとつなげる以上の機能がないなら、なくして

class Rate < ApplicationRecord belongs_to :user belongs_to :host end

rates = host.rates

投稿2022/04/05 22:24

winterboum

総合スコア23329

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

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

IRIESS

2022/04/06 12:19

まずモデル設計がよくないのですね。相談せず自分の感でつくってしまいました。今から変更すると骨が折れそうです agreementには他にもstatusなど機能があります! 回答ありがとうございました!
winterboum

2022/04/06 22:15

ということですと、もし修正するなら 前者 ですね
guest

0

ベストアンサー

個人的には他テーブルで絞り込みをする時は、mergeを使うのが好きです。他テーブルを参照しているのが、一目で分かるので。(勿論whereでも出来ますが)

ruby

1Rate.left_joins(:agreement).includes(agreement: :user).merge(Agreement.where(host_id: host.id))

投稿2022/04/05 09:15

esperer286

総合スコア30

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

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

IRIESS

2022/04/06 12:14

ありがとうございました!mergeを使ってみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問