アラーム、サイト、ネットワークの 3 つのモデルがあります。彼らは属している関係によって接続されていますが、異なるデータベースに住んでいます
class Alarm < ActiveRecord::Base
establish_connection :remote
belongs_to :site, primary_key: :mac_address, foreign_key: :mac_address
end
class Site < ActiveRecord::Base
establish_connection :remote
belongs_to :network
end
class Network < ActiveRecord::Base
establish_connection :local
end
特定のネットワークに属するすべてのアラームを選択したいと考えています。次のように、スコープ内で生のSQLを使用してこれを行うことができます。
scope :network_alarms, lambda { |net|
#need to ensure we are interrogating the right databases - network and site are local, alarm is remote
remote=Alarm.connection.current_database
local=Network.connection.current_database
Alarm.find_by_sql("SELECT network.* FROM #{local}.network INNER JOIN #{local}.site ON network.id = site.network_id INNER JOIN #{remote}.alarm on #{remote}.alarm.mac_address = site.mac_address WHERE site.network_id=#{net.id}")
}
これはうまくいきます。ただし、このスコープは配列を返すため、連鎖させることはできません (たとえば、with_paginate's #page
メソッドを使用するため)。そう
この結合を行うためのよりインテリジェントな方法はありますか。たとえば、join
andステートメントを使用してみました (これは、私が試した多くのバリエーションの 1 つです)。where
scope :network_alarms, lambda { |net| joins(:site).where("alarm.mac_address = site.mac_address").where('site.network_id=?', net) }
しかし、問題は、各テーブルが使用している接続をチェックせずに、レール#join
が両方のテーブルが同じデータベースにあると想定していることです。