2

バスの到着データを提供する API を使用しています。リクエストごとに、(とりわけ) どのルートが問題の停留所にサービスを提供しているかのリストを取得します。たとえば、リストにバス ルート #1、2、および 5 の結果が含まれている場合、それらがこの停留所にサービスを提供していることがわかります。

Route と Stop の間に多対多の関係が設定されており、リクエストごとにこれらの関連付けを動的にチェックして更新したいと考えています。どのルートがどの停留所にサービスを提供するかを示す「マスター リスト」は存在しないため、このデータを取得するにはこれが最善の方法のようです。

私が今やっている方法は非常に非効率的だと思います:

# routes is an array of [number, destination] that I build while iterating over the data
routes.uniq.each do |route|
  number      = route[0]
  destination = route[1]

  r = Route.find_by_number_and_destination(number, destination)

  if !r
    r = Route.new :number => number, :destination => destination
    r.save
  end

  # I have to check if it already exists because I can't find a way
  # to create a uniqueness constraint on the join table with 2 foreign keys
  r.stops << stop unless r.stops.include? stop
end

基本的に、見つけたルートごとに 2 つのことを行う必要があります。1) まだ存在しない場合は作成し、2) 現在の停留所がまだ存在しない場合は関係を追加します。

これを行うためのより良い方法はありますか?たとえば、現在行っている多数のデータベース呼び出しを回避するために、メモリ内のデータを大量に取得し、アプリ サーバー側で処理の一部を実行することはありますか?

4

3 に答える 3

1

この宝石を試してください: https://github.com/seamusabshere/upsert

ドキュメントによると、find_or_create_by よりも 80% 高速です。

于 2012-06-21T18:54:00.990 に答える
1

私が正しく理解できれば、あなたは 2 つのモデルを持っているはずです。Route モデルと Stop モデル。

これらのモデルを定義する方法は次のとおりです。

class Route < ActiveRecord::Base
  has_and_belongs_to_many :stops
  belongs_to :stop, :foreign_key => 'destination_id'
end

class Stop < ActiveRecorde::Base
  has_and_belongs_to_many :routes
end

テーブルをセットアップする方法は次のとおりです。

create_table :routes do |t|
  t.integer :destination_id
  # Any other information you want to store about routes
end

create_table :stops do |t|
  # Any other information you want to store about stops
end

create_table :routes_stops, :primary_key => [:route_id, :stop_id] do |t|
  t.integer :route_id
  t.integer :stop_id
end

最後に、使用するコードは次のとおりです。

# First, find all the relevant routes, just for caching.
Route.find(numbers)

r = Route.find(number)
r.destination_id = destination
r.stops << stop

これには、少数の SQL クエリのみを使用する必要があります。

于 2008-09-07T15:35:05.840 に答える
0

停止の呼び出しをクリーンアップする良い方法がある可能性がありますが、ルートがどのように構成されているかを適切に描写していると仮定すると、これでかなりクリーンアップされます。

routes.uniq.each do |number, destination|

  r = Route.find_or_create_by_number_and_destination(route[0], destination)

  r.stops << stop unless r.stops.include? stop

end
于 2012-03-06T03:43:06.583 に答える