1

Railsアプリのデータをプルするために必要なレガシーデータベースがあります。

各テーブルは、数字の接尾辞が付いた複数のテーブルに分割されます。各テーブルには、1日の4時間のデータが保持されます。

「widget_status」テーブルがあります。このテーブルは実際にはデータを保持していません。

既存のテーブルは次のとおりです。

  1. widget_status_0
  2. widget_status_1
  3. widget_status_2
  4. widget_status_3
  5. widget_status_4
  6. widget_status_53

各テーブルには4時間のデータが保持されます。

このクエリは機能します:

( SELECT timestamp, some_field FROM widget_status_0  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_1  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_2  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_3  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_4  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_5  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod ) LIMIT 200 

または類似のものを使用して6つの基礎となるテーブルをクエリするRailsモデル「ウィジェット」を作成しようとしているunionので、残りのコードは6つのテーブルを処理しようとすることを無視します。

このパターンに従う複数のテーブルがあり、6つのテーブルの処理を抽象化できるようにしたいので、残りのコードでは通常どおりfindなどを使用できます。ARELを使用してこれを行う方法を誰かが提案できますか?それとも、それが素晴らしくてシンプルな方法はありますか?

4

1 に答える 1

0

正確な答えではありません:残念ながら、DBビューを作成する能力がない限り(コメントで述べたように)、ARを使用してこの種のことを行う方法がわかりません。

DB ビューがないと、クエリ メソッドやオブジェクトの自動インスタンス化など、AR の魔法の多くが失われます。

ただし、arel はクエリを作成するのに役立ちます (注: 以下はテストされていないため、微調整が必​​要になる場合がありますが、その精神は理解できます)。

class WidgetStatus    

  # when given a block, this method will apply the same arel chain 
  # to all tables and union them.
  def self.build_query 
    (0..5).map do |i| 
      arel_chain = Arel::Table.new("widget_status_#{i}") 
      arel_chain = yield arel_chain if block_given?
      arel_chain
    end.inject(){|chain, next| chain.union next }
  end

end

今、あなたは次のようなアレルを行うことができます:

query = WidgetStatus.build_query do |table| 
  table
    .project( :timestamp, :some_field )
    .where( 
      table[:widget_sn].eq( @sn )
      .and( table[:timestamp].get( @t ) 
     )
end

ActiveRecord::Base.connection.select_all query有用なデータを取得するために使用します。

于 2013-02-12T12:00:49.190 に答える