【问题标题】:Rails does not save reference ID to record error: "Class must exist"Rails 不保存引用 ID 以记录错误:“类必须存在”
【发布时间】:2018-11-24 13:48:40
【问题描述】:

问题是我找不到为什么在创建新记录时无法插入引用列 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')

ShopPlanShopShop 中的plan_id 列链接

ShopAppApp中的shop_id列链接

我在用户访问索引时预先插入了一些值:

#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)由于在ShopShop_Plan 之间,我必须指定确切的列类,我使用手动plan_id 而不是使用默认的shopplans_id 列。 2) 我在 App 中更新了 1 列,除非只是在调试时进行检查。

【问题讨论】:

  • 当你复数你的has_many关联时会发生什么,所以has_many :shopshas_many :apps
  • @David 它仍然返回相同的结果,但只是提到我对Shop 的插入效果很好,问题只发生在App 插入。还是谢谢你
  • 为了使其正常工作,需要将 ShopPlan 中的关联更改为 has_many :shops, foreign_key: :plan_id。否则,rails 将无法从此端正确加入关联。您还可以将 App 中的关联更改为仅 belongs_to :shopbelongs_to :shop_plan, foreign_key: :plan_idclass_nameforeign_key 选项仅在无法从关联名称中推断出来时才需要。

标签: ruby-on-rails shopify


【解决方案1】:

首先,就像@David 指出的那样,您的关联名称不正确。您必须设置has_many :shopshas_many :apps,以便activerecord 知道如何找到正确的类。

其次,如果可以从关联名称中推断出类,则不必指定class_name 选项,因此可以是belongs_to :shopbelongs_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

【讨论】:

  • 谢谢,让我编辑我的问题,实际上应用程序会包含一些其他列,但由于敏感值,我无法在这里列出所有内容
  • @Jacky,create_app 方法接受带有 guides.rubyonrails.org/… 属性的哈希
【解决方案2】:

我找到了我的代码不起作用的愚蠢原因。 这不是因为as_many :shopshas_many :app,也不是因为我创建记录时的代码。

这只是因为在 app.shop_id = @shop.id, 的 App 中创建新记录时出现了愚蠢的逗号“,”,因为我一直在 Ruby 和 JavaScript 之间切换。感谢@arieljuod 和@David 的努力

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 2018-05-23
    • 2015-02-27
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2011-09-11
    • 2021-12-08
    相关资源
    最近更新 更多