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
I have found out the silly reason why my code does not work. It's not because
as_many :shops
andhas_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 effortFirst of all, like @David pointed out, your associations names are not right. You have to set
has_many :shops
andhas_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 bebelongs_to :shop
andbelongs_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