我正在尝试将对象保存到数据库并创建has_many
关联,但是验证失败。我目前正在使用Postgres在Rails 5.2上。
item.rb
class Item < ApplicationRecord
has_many :routings, dependent: :destroy
has_many :work_centers, through: :routings
validates :number, presence: true,
length: { maximum: 255 },
uniqueness: true
...
end
routing.rb
class Routing < ApplicationRecord
belongs_to :item
belongs_to :work_center
validates :item_id, presence: true
validates :work_center_id, presence: true
...
end
work_center.rb
class WorkCenter < ApplicationRecord
has_many :routings, dependent: :destroy
has_many :items, through: :routings
validates :name, presence: true, length: { maximum: 255 },
uniqueness: { case_sensitive: false }
validates :sequence, presence: true,
uniqueness: true
end
items_controller.rb
def create
@item = Item.new(item_params)
if @item.save
...
end
end
private
def item_params
params.require(:item).permit(:job_id, :number, :product_type, work_center_ids: [])
end
当我尝试在Rails控制台中创建新的Item
时,它会失败并显示验证错误:
> Item.create!(job_id: 58, number: "6872-ryan1", work_center_ids: [3,4])
ActiveRecord::RecordInvalid: Validation failed: Routings is invalid
但是,如果我先创建Item
然后添加Routings
,它将成功:
> i = Item.create!(job_id: 58, number: "6872-ryan1")
=> #<Item id: 583, number: "6872-ryan1", product_type: nil, job_id: 58, created_at: "2019-01-10 14:28:16", updated_at: "2019-01-10 14:28:16">
> i.work_center_ids = [3,4]
=> [3, 4]
我尝试将inverse_of:
添加到模型:
更新后的item.rb
class Item < ApplicationRecord
has_many :routings, dependent: :destroy
has_many :work_centers, through: :routings, inverse_of: :item
...
end
更新了work_center.rb
class WorkCenter < ApplicationRecord
has_many :routings, dependent: :destroy
has_many :items, through: :routings, inverse_of: :work_center
end
但是现在我得到了另一个错误:
> Item.create!(job_id: 58, number: "6872-ryan2", work_center_ids: [3])
ActiveRecord::InverseOfAssociationNotFoundError: Could not find the inverse association for work_centers (:item in WorkCenter)
已编辑以显示模型中的验证
答案 0 :(得分:1)
从ROR的第5版开始,belongs_to
关联默认情况下经过验证,因此在路由模型中不需要这些行:
validates :item_id, presence: true
validates :work_center_id, presence: true
如果删除后您可以在没有item_id或work_center_id的情况下创建路由,请在配置文件中将belongs_to_required_by_default = false
更改为true
。
无论如何,您应该验证关联模型的存在,而不是其ID。在前一种情况下,您检查数据库中是否存在具有给定id的项目(例如),在后一种情况下,您仅检查item_id
列是否具有某些值。