这段代码的验证错误怎么可能?

时间:2018-03-01 01:05:39

标签: ruby-on-rails ruby activerecord

错误为ActiveRecord::RecordInvalid: Validation failed: Route must exist

这是代码:

new_route = Route.create!(new_route_data)

new_points.each_with_index do |point, index|
  new_point_data = { route_id: new_route.id,
                     latitude: point[0],
                     longitude: point[1],
                     timestamp: point[2] }
  new_point = Point.create!(new_point_data)
end

正在报告new_point = Point.create!(new_point_data)行。

相关详细信息:

  • 如上所示,此代码在单个Sidekiq工作程序中运行(因此,路由不是在一个工作程序中创建的,而点是在另一个工作程序中创建的 - 这是全部内联的)
  • routes表几乎有3M记录
  • points表有大约2.5B记录
  • Point模型包含belongs_to :route, counter_cache: true
  • Route型号
  • 没有验证
  • 如果相关,Route模型确实包含belongs_to :user, counter_cache: true
  • users
  • 中只有约5k条记录

软件版本:

  • Rails 5.1.5
  • Ruby 2.5.0
  • PostgreSQL 9.6.7

2 个答案:

答案 0 :(得分:0)

首先,您的代码没有意义。您正在迭代 new_point 并将 new_point 分配给块中的某个值。所以我假设你的意思是迭代一些名为data_points的集合

试试这个。

在路线模型中

has_many :points

然后:

new_route = ...
data_points.each do |point|
  point_data = {latitude: point[0], ...}   # do not include route_id
  new_route.points.create(point_data) # idiomatic
end

` 你不需要索引,所以不要使用each_with_index。

答案 1 :(得分:0)

如果不了解Point模型中的验证类型,很难说出问题所在。

我的猜测是你在point.rb中的验证是:

validates :route, presence: true

使用ActiveRecord关系,您可以使用此快捷方式来避免显式分配route_id:

new_point_data = { latitude: point[0],longitude: point[1], timestamp: point[2] }
new_route.points.create!(new_point_data)

其中new_point数据没有route_id。

您还应该重命名要在块中指定的new_point,因为您正在重写您正在迭代的数组。