Rails不会保存引用ID来记录错误:“类必须存在”

时间:2018-11-24 13:48:41

标签: ruby-on-rails shopify

问题是我找不到创建新记录时为什么不能插入参考列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添加到a​​pp.db模型中时,它将插入null

感谢是否有人可以指出我为什么出现此错误

编辑:@arieljuod需要明确 1)由于ShopShop_Plan之间的关系,我必须使用特定的确切列类,我使用的是手动plan_id而不是默认的shopplans_id列。 2)我在App内更新了1列,所有这些都除非在调试时进行检查。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我发现了我的代码无法正常工作的愚蠢原因。 这不是因为as_many :shopshas_many :app,也不是因为我在创建记录时的代码。

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