我有以下简化的模型,以及使用Sqlite在rails项目中的控制器中的操作。
在我添加车库模型之前,cars控制器中的update动作工作正常。由于车库有很多汽车,而汽车有一个车库,因此我在迁移中指定了一个外键关系,在cars表中有garage_id。
在模型中添加“ has_many:cars”和“ belongs_to:garage”关系后,cars#update操作停止处理“ 404滚动回滚事务”错误。关联似乎有问题。
如何指定模型之间的正确关系?
class Garage < ApplicationRecord
has_many :cars
end
class User < ApplicationRecord
has_many :cars
end
class Car < ApplicationRecord
# car table has building_id as foreign key
belongs_to :garage
belongs_to :user
has_one :option
end
class Option < ApplicationRecord
# option table has car_id as foreign key
belongs_to :car
end
class CarsController < ApplicationController
def update
@car.update(params[:color])
@option.update(params[:seat])
# getting "404 rolling back transaction" error.
end
end
答案 0 :(得分:3)
从Rails 5开始,默认情况下假定belongs_to
关联是必需的。每当您尝试更新现有记录时,都会对此进行验证。
如果您建议Garage
是新车型,则您现有的汽车可能尚未分配车库。对汽车进行任何其他更改将检查所有验证,包括检查是否存在车库。如果您的汽车仍然没有,则验证将失败,并且更新事务将回滚。
如果您想继续使用有效属于零或一个车库的汽车,则可以将关联标记为可选:
belongs_to :garage, optional: true
如果您打算在将来某个时候要求将所有汽车分配到车库,则可以在所有汽车更新后删除optional
子句。或者,您可以硬着头皮,坚持将所有汽车分配给车库,然后再对它们进行任何其他更改。这取决于您,采取的措施取决于您的用例。
偶然地,调用@car.errors
后,验证失败应显示在@car.update
中。如果您将来会遇到回滚,那么这始终是最先了解发生情况的最佳位置。