2017-08-31 8 views
1

Railsアプリケーションでは、関連する(多対多の)テーブルが2つあります。ボリュームトラックです。生のSQLクエリを使用してActive Recordの関連付けを模倣する方法は?

ボリュームは、ラジオ番組のエピソードのコレクションです。各エピソードには複数のトラックがあります。しかし、各トラックは多くのショーに出演することができます。

ボリューム

id |   title 
-----+----------------------- 
23 | Oldstyle 
24 | How to stop worrying 

トラック

id |  artist  |   title 
------+----------------------+------------------------ 
4764 | John Lennon   | Mind Games 
4765 | George Harrison  | All Those Years Ago 
4766 | Paul McCartney  | Here Today 

私は必要なものアーティストの曲を集約し、そのアーティストの曲を持っているすべてのショーのボリュームを示すことです。 Artist.select(name: 'Beatles').volumesのようなものです。

問題はありませんアーティストモデルです。手動でのデータのクリーンアップがずっと難しくなると思うので、作成したくないです。

SELECT DISTINCT t.artist, v.number 
FROM tracks t 
JOIN volumes_tracks vt ON vt.track_id = t.id 
JOIN volumes v ON v.id = vt.volumes_id 
GROUP BY artist, number; 

しかし、それは容易なアクセスのために、それはモデルのようなデータ構造をラップすることが可能である:

例えば、私は、私は次のように必要なデータを照会することができますか?

+0

理由だけではなく、アーティストモデルを作成していませんか? あなたがパフォーマンスについて心配しているなら、あなたはそのモデルを持ちたいと思います。もしそうでなければ、決して掃除されないデータベース内のいくつかのアーティストレコードの害は何か? (そして、かなり簡単にきれいにすることができます: 'Artist.includes(:tracks).where({tracks:{id:nil}}))delete') – gernberg

+0

おそらく、あなたは正しいでしょう。私がArtistモデルを望んでいない唯一の理由は、マニュアルレビューデータをより複雑にするためです。トラックテーブルの行が壊れている場合があります。これは 'artist:" Bob Dylan-Blowng in the Wind "、トラック:" "'などです。しかし、私は少し複雑な結合クエリでこのような問題を克服することができます。 – vtambourine

答えて

0

sqlクエリによって返された各結果を構造体にマップすることができます。これにより、探しているアクセスが容易になります。このような何か:

Artist = Struct.new(:artist, :volume_id) 
    result=ActiveRecord::Base.connection.execute(sql) 
    artists = result.map{|r| Artist.new(r['t.artist'], r['v.id']} 
    first_artist = artists[0].artist 

(SQL変数は、SQLクエリ文字列を表します)

関連する問題