Rails build belongs_to association "must exist" error
Asked Answered
T

2

6

I am trying to build a has_many model in the belongs_to model association in rails. The association is correct, but it shows error "must exist". I tried putting the optional: true, but it does not seem to be working.

Models

class User::Product < ApplicationRecord
  has_one: :promo_code
end

class User::PromoCode < ApplicationRecord
  belongs_to: :product, optional: true
  accepts_nested_attributes_for :product
end

PromoCodesController

def new
  @promo_code = User::PromoCode.new
  @product.build_product
end

def create
  @promo_code = User::PromoCode.new(promo_code_params)
  @promo_code.save
end

def promo_code_params
  params.require(:user_promo_code).permit(:product_id, :product_attributes => [:name])
end

form

form_with(model: promo_code) do |form|
  form.fields_for :product do |f|
    f.text_field :name
  end
end

When the form saves an error appears saying "must exist", which I am assuming is referring to the foreign key in belongs_to.

Any ideas in what I can be doing wrong? I think the code above is the only relevant code that I have regarding this issue.

Thales answered 17/8, 2018 at 14:28 Comment(3)
Do you have a top level Product as well as a User::Product?Knighthood
@Knighthood no User is just the namespace.Thales
See Here seems like this is a known issue although optional: true should have solved thisKnighthood
D
8

Looking into the issue linked by @engineersmnky, it looks as if this is a known bug when using accepts_nested_attributes_for.

This can be solved by using the inverse_of option to clarify the bi-directional relationship:

class User::Product < ApplicationRecord
  has_one: :promo_code, inverse_of: :product
end

class User::PromoCode < ApplicationRecord
  belongs_to: :product, optional: true, inverse_of: :promo_code
  accepts_nested_attributes_for :product
end

Try that and see if it resolves your problem.

Dispense answered 17/8, 2018 at 15:24 Comment(2)
Argh, shame, thanks for letting me know - give @chrisgeeq's answer a shot, seems to be the other suggestion in that thread, that has helped where inverse_of hasn't. That's one mean bug though, hope you get it sorted soon!Dispense
For some reason, it never complained before but the issue was in a different part of the code. Changed that and the relation works with or without the inverse of. Thanks for your help!Thales
U
1

try this in the models respectively

 has_one :promo_code, -> { PromoCode.order(:id) }, class_name: 'PromoCode',inverse_of: :product


belongs_to :product, inverse_of: :promo_code
Urissa answered 17/8, 2018 at 16:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.