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

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

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

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

Q&A

解決済

1回答

1180閲覧

[Rails]中間テーブルを経由したデータ取得のエラー Unknown column

teriyakburger

総合スコア1

Ruby on Rails

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

0グッド

0クリップ

投稿2021/06/02 11:02

編集2021/06/02 14:58

前提・実現したいこと

Ruby on Railsで、ねこ特化型のインスタグラムのようなアプリを作っています。
User <- relationships経由 -> Cat <- cat_photos経由 -> Photo
というアソシエーションを組んでいます。
ユーザーがフォローしているねこたちの写真一覧表示機能を実装中に、以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

ActiveRecord::StatementInvalid in Cats#index Showing /Users/username/projects/nyanstagram/app/views/cats/index.html.erb where line #9 raised: Mysql2::Error: Unknown column 'photos.cat_ids' in 'IN/ALL/ANY subquery' Extracted source (around line #9): 7 8 9 10 11 12 <h4 class="text-center">FOLLOWING'S NEW PHOTOS</h4> </div> <% if @following_cats_photos.present? %> <div class="row d-flex justify-content-around"> <% @following_cats_photos.each do |photo| %> <div class="col-sm-4 mb-3"> Rails.root: /Users/username/projects/nyanstagram Application Trace | Framework Trace | Full Trace app/views/cats/index.html.erb:9 Request Parameters: None

該当のソースコード

Ruby

1//Catsコントローラー 2 3 def index 4 @photos = Photo.includes(:cats).order('created_at DESC').limit(6) 5 @cats = Cat.order('created_at DESC').limit(6) 6 if user_signed_in? && current_user.following.present? 7 @user = User.includes(:following).find(current_user.id) 8 @following_cats = @user.following 9 @following_cats_photos = Photo.where(cat_ids: @following_cats).order('created_at DESC').limit(6) 10 end 11 end

HTML

1//該当ページHTML 2<!--新着写真(フォロー)--> 3<% if @following_cats.present? %> 4 <div class="container mt-5"> 5 <div class="row mt-5 pt-4 mb-5 d-inline"> 6 <h4 class="text-center">FOLLOWING'S NEW PHOTOS</h4> 7 </div> 8 <% if @following_cats_photos.present? %> 9 <div class="row d-flex justify-content-around"> 10 <% @following_cats_photos.each do |photo| %> 11 <div class="col-sm-4 mb-3"> 12 <div class="card border-0"> 13 <%= link_to photo_path(photo) do %> 14 <%= image_tag photo.cat_photo, class: "card-img-top" %> 15 <% end %> 16 <div class="d-flex flex-row justify-content-between p-2"> 17 <h6 class="card-title"><%= photo.detail %></h6> 18 <div class="like-btn card-text"> 19 <%= render 'likes/like', photo: photo %> 20 </div> 21 </div> 22 </div> 23 </div> 24 <% end %> 25 </div> 26 <% else %> 27 <div class="text-center"> 28 <p>フォローしているねこちゃんはまだ写真が投稿されていないみたいです。</p> 29 </div> 30 <% end %> 31 </div> 32<% end %>

Ruby

1//Userモデル 2class User < ApplicationRecord 3 # Include default devise modules. Others available are: 4 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 5 devise :database_authenticatable, :registerable, 6 :recoverable, :rememberable, :validatable 7 8 has_many :cats, dependent: :destroy 9 has_many :photos, dependent: :destroy 10 11 # フォロー関連 12 has_many :relationships 13 has_many :following, through: :relationships, source: :cat 14end

Ruby

1 2//Catモデル 3 4class Cat < ApplicationRecord 5 has_many :cat_photos, dependent: :destroy 6 has_many :photos, through: :cat_photos 7 belongs_to :user 8 has_one_attached :icon 9 以下略

Ruby

1//Photoモデル 2class Photo < ApplicationRecord 3 has_many :cat_photos, dependent: :destroy 4 has_many :cats, through: :cat_photos 5 has_one_attached :cat_photo 6 belongs_to :user 7 以下略

Ruby

1//Cat_Photo中間テーブル 2class CatPhoto < ApplicationRecord 3 belongs_to :cat 4 belongs_to :photo 5end

Ruby

1//フォロー用User_Cat中間モデル 2class Relationship < ApplicationRecord 3 belongs_to :user 4 belongs_to :cat 5 6 with_options presence: true do 7 validates :user_id, :cat_id 8 end 9end

Ruby

1//Catモデルマイグレーション 2 3class CreateCats < ActiveRecord::Migration[6.0] 4 def change 5 create_table :cats do |t| 6 t.string :cat_name, null: false 7 t.integer :cat_sex_id 8 t.integer :cat_age 9 t.integer :cat_breed_id 10 t.timestamps 11 end 12 end 13end 14 15//追記 16class AddUserIdToCats < ActiveRecord::Migration[6.0] 17 def change 18 add_reference :cats, :user, null: false, foreign_key: true 19 end 20end 21

Ruby

1//Photoモデルマイグレーション 2class CreatePhotos < ActiveRecord::Migration[6.0] 3 def change 4 create_table :photos do |t| 5 t.text :detail 6 t.timestamps 7 end 8 end 9end 10//追記 11class AddReferencesToPhotos < ActiveRecord::Migration[6.0] 12 def change 13 add_reference :photos, :user, null: false, foreign_key: true 14 end 15end 16

Ruby

1Cat-Photo中間テーブルマイグレーション 2 3class CreateCatPhotos < ActiveRecord::Migration[6.0] 4 def change 5 create_table :cat_photos do |t| 6 t.references :cat, null: false, foreign_key: true 7 t.references :photo, null: false, foreign_key: true 8 t.timestamps 9 end 10 end 11end

Ruby

1User-Catフォロー関係用テーブルマイグレーション 2 3class CreateRelationships < ActiveRecord::Migration[6.0] 4 def change 5 create_table :relationships do |t| 6 t.references :user, foreign_key: true 7 t.references :cat, foreign_key: true 8 9 t.timestamps 10 11 t.index %i[user_id cat_id], unique: true 12 end 13 end 14end

試したこと

Catsコントローラー内@following_cats_photos = Photo.where(cat_ids: @following_cats).order('created_at DESC').limit(6)@following_cats_photos = Photo.where(cats: @following_cats).order('created_at DESC').limit(6)に変えてみました。
写真が表示されるようになりましたが、cat_idではなくphoto_idを参照しているようで、フォロー関係ではない猫の写真が出てしまいました。
中間テーブルのアソシエーションがうまくいってないのではないかと思いますが、@photo.catsなどで猫情報を引き出すこと、またその逆の@cat.photosで写真を引き出すことは可能でした。

補足情報(FW/ツールのバージョンなど)

Ruby 2.6.5
Rails 6.0.3.6

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

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

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

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

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

m.ts10806

2021/06/02 11:06

Model定義だけじゃなく、マイグレーションファイルも提示されたほうが良いと思います。テーブル定義そのものも影響がないとは言い切れません。 現にカラムが存在しないことを指摘されているわけですから。
winterboum

2021/06/02 11:31

user modelも載せて。 @following_cats = @user.following がわからない
teriyakburger

2021/06/02 11:41

ご確認いただきありがとうございます! マイグレーションファイルとuser modelを追記いたしました。
winterboum

2021/06/02 13:23

そうしますと`@user.following` これはmethod? でしたらそれも載せて
teriyakburger

2021/06/02 15:01

記載漏れ大変失礼いたしました。 正しくはuserとcatの間にrelationshipsテーブルを挟んでuserがcatをフォローできるようにしており、その関係性で@user.followingを使用しておりました。
guest

回答1

0

ベストアンサー

catとphotoが多対多ですか? 1枚の写真に複数の猫が写ってるから?
そうしますとなかなか厄介ですね。

Photo.where(cat_ids: @following_cats)

@following_cats.map(&:photos).flatten なら簡単に書けますがこれだとdatabaseにてorderかけられないので取り込んでからsortになりますね。
あとその手前で適切にincludesしておかないと1:N問題が起きます。
Photo.joins(:cat_photos),where("cat_photos.cats_id": @following_cats.map(&:cat_id))
で行けるかな。これならorderかかります

投稿2021/06/02 23:26

winterboum

総合スコア23329

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

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

teriyakburger

2021/06/03 08:16 編集

はい、一枚の写真に複数の猫が写っているため、catとphotoを多対多の関係に設定してあります。 ご教示いただいたコードで試したところ、cats_idやcat_idのところで何回かunknown columnが出てしまいましたが、最終的に ----------------------------------------------------------------------- Photo.joins(:cat_photos).where("cat_photos.cat_id": @following_cats.map(&:id)) ----------------------------------------------------------------------- で無事想定していた動作ができました! orderもlimitも掛かることを確認できました。 最終的に変更したコードは以下の通りです。 ----------------------------------------------------------------------- //catsコントローラー def index @photos = Photo.includes(:cats).order('created_at DESC').limit(6) @cats = Cat.order('created_at DESC').limit(6) if user_signed_in? && current_user.following.present? @user = User.includes(:following).find(current_user.id)   ## ご指摘いただいた1:N問題対策に、ここでphotosをincludesしました @following_cats = @user.following.includes(:photos) @following_cats_photos = Photo.joins(:cat_photos).where("cat_photos.cat_id": @following_cats.map(&:id)).order('created_at DESC').limit(6) end end ----------------------------------------------------------------------- ご助力いただき誠にありがとうございました! いくら考えても自分では解決できなかったと思うので、本当に助かりました。 一緒に考えてくださったみなさま、本当にありがとうございました!
winterboum

2021/06/03 08:39

そか、@following_cats は Cat でしたね。 1:N問題対策がすっと出来てしまうのですからなかなか出来ますね。 追加質問があるだろうとおもってました
teriyakburger

2021/06/03 09:53

いえいえ、ご指摘いただくまで1:N問題に全く気づけなかったので、お恥ずかしい限りです。 ちゃんと対策になっているようでよかったです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問