0

非常に複雑なクエリ (2 つの町の間のバス接続を見つける) があり、結合からデータにアクセスする方法がわかりません (どの停留所で接続が開始され、どの停留所で接続が開始されるかを知りたいです)。終わり)。ActiveRecord を使用してこのデータにアクセスすることは可能ですか?

Course.joins("INNER JOIN stop_times as start_stop ON start_stop.course_id=courses.id")
.joins("INNER JOIN stop_times as end_stop ON end_stop.course_id = courses.id")
.joins('INNER JOIN stops as start_stopi ON start_stop.stop_id = start_stopi.id')
.joins('INNER JOIN stops as end_stopi ON end_stop.stop_id = end_stopi.id')
.where('start_stop.hour>= ? OR (start_stop.hour>= ? AND start_stop.minute>= ?)',hour,(hour+1)%24,minute)
.where('start_stopi.town_id = ? and end_stopi.town_id = ?',start_town,end_town)
.where('start_stop."order"<end_stop."order"').order('start_stop.minute ASC').order('start_stop.hour ASC')

編集:アクティブなレコード結合を使用するように書き直すことができましたが、名前が壊れましたが、動作します。

Course.joins(end_stop_times: :stop).joins(start_stop_times: :stop)
.where('start_stop_times_courses.hour>= ? OR (start_stop_times_courses.hour>= ? AND start_stop_times_courses.minute>= ?)',hour,(hour+1)%24,minute)
.where('stops_stop_times.town_id = ? and stops.town_id = ?',start_town,end_town)
.where('start_stop_times_courses."order"<stop_times."order"')
.order('start_stop_times_courses.minute ASC').order('start_stop_times_courses.hour ASC')

この新しいクエリ モデルを使用すると、次のようになります。

class Course < ActiveRecord::Base
  belongs_to :carrier
  has_many :end_stop_times, class_name: 'StopTime'
  has_many :start_stop_times, class_name: 'StopTime'

class Stop < ActiveRecord::Base
  belongs_to :town

class StopTime < ActiveRecord::Base
  belongs_to :stop
  belongs_to :course
4

3 に答える 3

0

このクエリの出力をログで確認してください。ログが で始まることがわかります。select courses.*したがって、含まれているテーブルからデータを取得することはできません。

クエリにいくつかのステートメントを追加できselect other_table.some_columnますが、これは Rails の方法ではありません。

スコープを関連するモデルに分離することをお勧めしますstop_times。実際にデータを取得したいオブジェクトのスコープを呼び出すことができるように、スコープをモデル (およびその他) に配置します。

于 2013-09-16T16:13:30.803 に答える
0

次のように sth を追加する必要があります。

your_query.select('courses.*, start_stopi.id as start_stop_id, end_stopi.id as end_stop_id)

そして、コースオブジェクトで start_stop_id と end_stop_id を呼び出すことでアクセスできます。

ただし、この種の操作にはおそらく関連付けを使用する必要があります。モデルを見せていただけますか?

于 2013-09-16T16:07:08.670 に答える
0

あれほど複雑なカスタム SQL を構築しているとしたら、Rails のやり方を使いすぎていると思います。それを構築するために実際にはアクティブレコードの関連付け情報を使用しておらず、恐ろしく醜く読みにくいプログラミング構造を構築しました。

適切にフォーマットされたSQLと同様に書き直すことをお勧めします

results  = ActiveRecord::Base.connection.execute(
"select c.*
 from   courses    c
 join   stop_times ss on ss.course_id = c.id
 join   stop_times es on es.course_id = c.id
 ... etc ...
 where  (start_stop.hour  >= #{ActiveRecord::Base.sanitize(hour)} or
        ... etc ...")

これで、モデルと関連付けを、このレベルの複雑さが不要になるまで改善できる可能性があります (たとえば、コース間の関連付け、stop_times (開始) と stop_times (終了) は、おそらく activerecord でかなりうまくカプセル化できますが、現時点では、純粋な SQL と純粋なアクティブレコードのアプローチの間で非常に不快な方法で落ちているようです。

于 2013-09-16T16:29:06.670 に答える