skip to Main Content

Issue is I can’t find why reference column id can’t be inserted when create new record.

I have 3 table shop_plan, shop and app

Below is tables schema:

  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"

And below is Model

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

There will be 1 default record added in seed.db for table shop_plan

ShopPlan.create(name: 'Basic')

ShopPlan and Shop are linked by plan_id column in Shop

Shop and App are linked by shop_id column in App

I pre-insert some value when user access index:

#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

This insert works well, however, when i run 2nd insert:

@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

error occurs as somehow app.shop_id will not add in my @shop.id and it will return will error: {"shop":["must exist"]}

I even try hard-code app.shop_id =1 but it does not help and when I add in optional: true to app.db model, it will insert null

Appreciate if anyone can help point out why I get this error

EDIT: @arieljuod to be clear
1) I have to specific exact column class due to between Shop And Shop_Plan, i’m using a manual plan_id instead of using default shopplans_id columns.
2) I have update 1 column inside App and all that unless is just to do checking when debugging.

2

Answers


  1. Chosen as BEST ANSWER

    I have found out the silly reason why my code does not work. It's not because as_many :shops and has_many :app and also not because my code when creating the record.

    It just due to silly comma ',' when creating new record in App at app.shop_id = @shop.id,, as I was keep switching between Ruby and JavaScript. Thank you @arieljuod and @David for your effort


  2. First of all, like @David pointed out, your associations names are not right. You have to set has_many :shops and has_many :apps so activerecord knows how to find the correct classes.

    Second, you don’t have to specify the class_name option if the class can be infered from the association name, so it can be belongs_to :shop and belongs_to :shop_plan, foreign_key: :plan_id. It works just fine with your setup, it’s just a suggestion to remove unnecesary code.

    Now, for your relationships, I think you shouldn’t do those first any? new block manually, rails can handle those for you.

    you could do something like

    @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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search