如何在Rails中向上添加一堆ActiveRecord对象和关系?

时间:2020-03-05 18:48:55  来源:igfitidea点击:

我正在使用提供公交车到达数据的API。对于每一个请求,我都会(除其他事项外)获得一份清单,其中列出了服务该站点的路线。例如,如果列表中包含#1、2和5号公交车路线的结果,那么我知道这些路线为本站提供了服务。

我在"路由"和"停止"之间建立了多对多关系,并且我想根据每个请求动态检查和更新这些关联。没有"主列表",其中列出了哪些路线服务于哪个站点,因此这似乎是获取此数据的最佳方法。

我认为我现在的做法效率很低:

# 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

基本上,我必须为发现的每条路线做两件事:
1)如果尚不存在,则创建它; 2)如果尚不存在,则向当前停靠处添加一个关系。

是否有更好的方法来做到这一点,例如通过在内存中获取一堆数据并在应用程序服务器端进行一些处理,以避免我当前正在进行的大量数据库调用?

解决方案

回答

如果我做对了,我们(应该)有2个模型。路线模型和停止模型。

这是我定义这些模型的方式:

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查询。