ruby-on-rails - Rails 不保存引用 ID 以记录错误:“类必须存在”
问题描述
问题是我找不到为什么在创建新记录时无法插入参考列 ID。
我有 3 张表 shop_plan、shop 和 app
以下是表架构:
create_table "shop_plans", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "shops", force: :cascade do |t|
t.string "url"
t.bigint "plan_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["plan_id"], name: "index_shops_on_plan_id"
end
create_table "apps", force: :cascade do |t|
t.bigint "shop_id"
t.binint "amount"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["app_id"], name: "index_apps_on_shop_id"
end
add_foreign_key "shops", "shop_plans", column: "plan_id"
add_foreign_key "apps", "shops"
下面是模型
class ShopPlan < ApplicationRecord
has_many :shop
end
class Shop < ApplicationRecord
belongs_to :shop_plan, class_name: 'ShopPlan', foreign_key: :plan_id
has_many :app
end
class App < ApplicationRecord
belongs_to :shop, class_name: 'Shop', foreign_key: :shop_id
end
将在seed.db 中为表shop_plan 添加1 条默认记录
ShopPlan.create(name: 'Basic')
ShopPlan和Shop按plan_id
列链接Shop
商店和应用程序按shop_id
列链接App
我在用户访问索引时预先插入了一些值:
#basic_plan
@basicPlan = ShopPlan.where(name: "Basic").first
# if new shop registered, add to database
unless Shop.where(url: @shop_session.url).any?
shop = Shop.new
shop.url = @shop_session.url
shop.plan_id = @basicPlan.id
shop.save
end
但是,当我运行第二次插入时,此插入效果很好:
@shop= Shop.where(url: @shop_session.url).first
unless App.where(shop_id: @shop.id).any?
app = App.new
app.shop_id = @shop.id,
app.amount = 10
app.save
end
发生错误,因为不知何故app.shop_id
不会添加到我的@shop.id
,它会返回错误:{"shop":["must exist"]}
我什至尝试硬编码app.shop_id =1
,但它没有帮助,当我添加optional: true
到 app.db 模型时,它会插入null
感谢是否有人可以帮助指出我收到此错误的原因
编辑:@arieljuod 要明确 1)由于介于Shop
And之间Shop_Plan
,我必须指定确切的列类,我使用的是手册plan_id
而不是使用默认shopplans_id
列。2)我在 App 内更新了 1 列,除非只是在调试时进行检查。
解决方案
首先,就像@David 指出的那样,您的关联名称不正确。您必须进行设置has_many :shops
,has_many :apps
因此 activerecord 知道如何找到正确的类。
其次,如果可以从关联名称中推断出类,则不必指定class_name
选项,因此可以是belongs_to :shop
and belongs_to :shop_plan, foreign_key: :plan_id
。它适用于您的设置,只是建议删除不必要的代码。
现在,对于您的关系,我认为您不应该first
any?
new
手动执行这些块,rails 可以为您处理这些块。
你可以做类似的事情
@basicPlan = ShopPlan.find_by(name: "Basic")
#this gives you the first record or creates a new one
@shop = @basicPlan.shops.where(url: @shop_session.url).first_or_create
#this will return the "app" of the shop if it already exists, and, if nil, it will create a new one
@app = @shop.app or @shop.create_app
推荐阅读
- redux - ngrx 中的参数化选择器的类型未知
- reactjs - React Ant 设计文件仅上传 xls 文件验证
- laravel - Select2 templateResult 不适用于触发器更改
- python - 在这个卷积神经网络机器学习模型中,我应该用什么替换“test_images”和“test_labels”?
- c# - 如果结构具有 ReadOnlySpan 字段,如何将 ref struct 参数传递给 MethodInfo
- asp.net - 如何显示正确的值?
- excel - VBA 合并日期和时间并转移到现有日期列
- html - 导航栏没有响应点击
- javascript - 如何显示 URL 中带有随机数的图像?
- batch-file - 使用批处理脚本将段落输出到 txt 文件