【发布时间】:2018-03-02 03:25:40
【问题描述】:
错误是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
【问题讨论】:
-
你需要做这个作业吗?
new_point = Point.create!(new_point_data)... 你能尝试只做Point.create!(new_point_data)并在new_point_data中设置route: new_route而不是route_id: new_route.id -
是的,我赞同上述观点。如果您在
Point中的验证是validates :route, presence: true,那么您应该将属性传递为route: new_route而不是route_id: new_route.id,因为验证是在route上,而不是route_id -
我将尝试直接引用
activity而不是activity.id并在监视一下(可能需要几天)后在这里跟进。我稍后会使用new_point.id,这就是为什么我(我认为我)需要做这个任务。 -
可能是 Sidekiq 太快了,new_route 在尝试访问它之前还没有提交到数据库。您可能需要确保 new_route.id 在分配之前可用。
-
@EJ2015 这真的是 sidekiq 太快了吗?在这一点上,它只是 ruby 代码——所有这些都发生在一个进程中。如果
new_route尚未提交到数据库,我难道不希望这些错误任何地方出现在我的 Rails 应用程序中吗?
标签: ruby-on-rails ruby activerecord