Rails не сохраняет ссылочный идентификатор в записи об ошибке: «класс должен существовать» - PullRequest
0 голосов
/ 24 ноября 2018

Проблема в том, что я не могу найти, почему идентификатор ссылочного столбца не может быть вставлен при создании новой записи.

У меня есть 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

Будет добавлена ​​1 запись по умолчанию в seed.db для таблицы shop_plan

ShopPlan.create(name: 'Basic')

ShopPlan и Магазин связаны столбцом 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 и Shop_Plan, я использую ручной plan_id вместо использования по умолчанию shopplans_id столбцов.2) У меня есть обновление 1 столбца внутри приложения, и все это, если только не делать проверки при отладке.

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Я обнаружил глупую причину, по которой мой код не работает.Это не потому, что as_many :shops и has_many :app, а также не потому, что мой код при создании записи.

Это просто из-за глупой запятой ',' при создании новой записи в App на app.shop_id = @shop.id,, как я былпродолжайте переключаться между Ruby и JavaScript.Спасибо @arieljuod и @David за ваши усилия

0 голосов
/ 24 ноября 2018

Прежде всего, как заметил @David, названия ваших ассоциаций неверны.Вы должны установить has_many :shops и has_many :apps, чтобы activerecord знала, как найти правильные классы.

Во-вторых, вам не нужно указывать опцию class_name, если класс может быть выведен из ассоциацииимя, так что это может быть belongs_to :shop и 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...