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

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

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

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

Ruby

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

Active Record

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

Q&A

解決済

1回答

935閲覧

多対多の関係のテーブルにて、複数のレコードを条件に複数のレコードを取得したい

takuan1108

総合スコア56

Ruby on Rails 5

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

Ruby

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

Active Record

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

0グッド

1クリップ

投稿2019/04/09 09:10

編集2019/04/09 09:11

多対多の関係のテーブルにて、複数のレコードを条件に複数のレコードを取得したい

Ruby on Railsでイベント検索のシステムを作っています。
Active Recordで効率的にレコードを取得する方法を模索しているのですが、
なかなか思ったように行かずに困っています…
もし助けていただけたら嬉しいです!

概要としては、
ユーザーにタグからイベントを検索してもらうために、
タグ一覧をトップページに表示したいのですが、
Tag.allで全てのタグを表示すると、それに紐づくイベントがない可能性もあるため、
"今募集中のイベント"に紐付く"タグ"だけを取得したいと考えています。

該当のソースコード

Ruby

1def prepare_search 2 @events = Event.where("date >= ?", Date.today) 3 @tags = @events.map{|event| event.tags}.flatten 4end

Ruby

1class Event < ApplicationRecord 2 has_many :event_tags 3 has_many :tags, through: :event_tags 4end

Ruby

1class Tag < ApplicationRecord 2 has_many :event_tags 3 has_many :events, through: :event_tags 4end

Ruby

1class EventTag < ApplicationRecord 2 belongs_to :event 3 belongs_to :tag 4end

試したこと

上記以外でいくつか方法を試してみたのですが、どれもうまく行かずにいます…

Ruby

1@tags = Tag.merge(Event.where(id: @events)) 2@tags = Tag.joins(:events).where("event_id = ?", @events.ids) 3@tags = Tag.includes(:events).where({events: @events})

そもそもの多対多のアソシエーションがどういうSQL文を作るのかをよく理解していないのかもしれません…

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

ruby '2.5.1'
rails '5.2.2'

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

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

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

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

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

satoshih

2019/04/10 07:22

> Active Recordで効率的にレコードを取得する方法を模索しているのですが これは具体的にどのようになれば効率的と言えるのでしょうか?
takuan1108

2019/04/10 11:28

ご返信ありがとうございます! 大きくは2つありまして、 ①N+1問題回避のためにmapメソッドを使わずに@tagsを取得したい。 ②ビューで@tags.limit(4)みたいに、limitを使いたいため、ひとつのActiveRecord::Relationインスタンスを取得したい。 正直①に関してもそんなに@eventが多くなる予定もありませんし、 ②に関してもmapで取得した後繰り返し処理をすればいいのではないかとも思ったのですが、 どうもそれがスマートなやり方に思えなかったのです。。
guest

回答1

0

自己解決

解決しましたー!

@events = Event.where("date >= ?", Date.today) @tags = Tag.joins(:events).merge(Event.where(id: @events.ids))

SELECT `tags`.* FROM `tags` INNER JOIN `event_tags` ON `event_tags`.`tag_id` = `tags`.`id` INNER JOIN `events` ON `events`.`id` = `event_tags`.`event_id` WHERE `events`.`id` IN (1, 2, 3, 4, 5, 6, 7)

joins(:events)で内部結合をしたうえで、mergeで直接where文をきっちり書いてあげることで解決しました!
satoshihさん、考えてくださってありがとうございました!

投稿2019/04/10 14:37

takuan1108

総合スコア56

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

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

satoshih

2019/04/11 02:25 編集

解決できたようで良かったです。 蛇足ですが、N+1については ``` @events = Event.where("date >= ?", Date.today).includes(:tags) ``` のように先読みすると解決するかもしれません。 ご参考までに。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問