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

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

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

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

Ruby on Rails

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

Active Record

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

Q&A

解決済

1回答

2244閲覧

has_many の最新の1件だけを include したテーブルを作りたい

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

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

Ruby on Rails

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

Active Record

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

0グッド

0クリップ

投稿2018/12/25 03:57

編集2018/12/25 04:09
class User < ActiveRecord::Base has_many :acts end

user のフィールドと最新の1件の acts のフィールドにアクセスしたい (select で取り出したい)

User.where(...).each{|user| user.name user.acts.last.field1 user.acts.last.field2

とかくと SQL アクセスが複数回呼ばれてしまいます

これを最初の1回のアクセスでフィールドに子テーブルの内容をまぜるにはどうすればいいんでしょうか
(user.field1) でアクセスできるようにしたい

User.where(...).includes(:acts) だと acts のフィールドは取り出せますが
has_many してる子要素が全て生成されてしまい each で回すと同じユーザのカラムが複数出力されてしまいます
最新の1件だけを join したテーブルを取り出すにはどうかけばいいんでしょうか

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

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

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

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

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

guest

回答1

0

ベストアンサー

最新の基準が単純ではないのでSQLで頑張る必要があると思います
ただしRails部分は scope, has_one を使って利用を便利にすることはできるでしょう

1. 更新がなくIDで最新が判断できる場合

ruby

1class User < ActiveRecord::Base 2 has_many :acts 3 has_one :latest_act, -> { latest }, class_name: 'Act' 4end 5 6class Act < ActiveRecord::Base 7 scope :latest, (lambda do 8 joins(<<~SQL.squish.freeze) 9 INNER JOIN ( 10 SELECT user_id, MAX(id) AS id 11 FROM acts 12 GROUP BY user_id 13 ) AS latests 14 ON latests.user_id = acts.user_id 15 AND latests.id = acts.id 16 SQL 17 end) 18end 19 20# includes で定義した最新のactと結合&参照すればOK 21User.where(***).includes(:latest_act)

2. 最終更新日が最も新しいものが最新の場合

ActiveRecord 周りは上記と同じですがSQLが複雑になると思います
IDと違って最終更新日時は理屈上は一致する可能性があるからです

投稿2018/12/25 08:58

Ighrs

総合スコア656

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

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

退会済みユーザー

退会済みユーザー

2018/12/25 09:17

group_by で MAXID を集計してからその MAXID と同じものを取得というプロセスが必要になるのですね… lambda や<<~SQL.squish.freezeのような記述もはじめてみたので調べてみます ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問