如何在Rails中插入一堆ActiveRecord对象和关系?

时间:2008-09-07 08:10:00

标签: ruby-on-rails activerecord

我正在使用提供总线到达数据的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

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

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

3 个答案:

答案 0 :(得分:1)

如果我做对了,你(应该)有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查询。

答案 1 :(得分:1)

试试这个宝石: https://github.com/seamusabshere/upsert

文档说它比find_or_create_by快80%

答案 2 :(得分: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