I have a concern that creates an association:
# concerns/product.rb
module Product
extend ActiveSupport::Concern
included do
has_many :products, class_name: "Product", foreign_key: :owner_id
end
end
And an example model:
# models/user.rb
class User < ApplicationRecord
include Product
end
If I do: User.products.last
it works fine. I also want to be able to do Product.last.owner
but it won't work without the association being defined. I can't define it in the Product model since I have no clue to what models will include the concern that creates the association.
I have tried creating the association using inverse_of:
class Product < ApplicationRecord
belongs_to :owner, inverse_of: :products
end
... but it won't work, apparently it needs a class name.
I've also tried reflecting on which classes the concern gets included within but it raises some strange errors when the concern gets included into several different models.
How do I create the inverse of an association from within the concern?
CodePudding user response:
As pointed out by @engineersmnky you can't actually setup an association that points to a bunch of different classes without using polymorphism*:
# you can't have a class and a module with the same name in Ruby
# reopening the class/module will cause a TypeError
module ProductOwner
extend ActiveSupport::Concern
included do
has_many :products, as: :owner
end
end
class Product < ApplicationRecord
belongs_to :owner,
inverse_of: :products,
polymorphic: true
end
class User < ApplicationRecord
include ProductOwner
end
The information about what you're actually joining has to be stored somewhere on the products table. If you don't use polymorphism you just have an integer (or UUID) which will always refer to a single table.