clowne-rb/clowne

polymorphic association

alessandromacagno opened this issue · 2 comments

Hi guys!

First of all congrats for your awesome gem. I'm opening an issue because I didn't find anywhere documentation for polymorphic tables, and I think the current behaviour is not as intended.

Example to reproduce. The table tag mapping has a polymorphic field owner (owner_id and owner_type)

# app/models/a.rb
class A < ApplicationRecord
  has_many :tag_mappings
  has_many :tags, through: tag_mappings
end

# app/models/b.rb
class B < ApplicationRecord
  has_many :tag_mappings
  has_many :tags, through: tag_mappings
end

# app/models/tag_mapping.rb
class TagMapping < ApplicationRecord
  belongs_to :tag
  belongs_to :owner, polymorphic: true
end

# app/models/tag.rb
class Tag < ApplicationRecord
  has_many :tag_mappings, dependent: :destroy
  has_many :as, through: :tag_mappings, source: :owner
  has_many :bs, through: :tag_mappings, source: :owner
end

Cloner

class ACloner < Common::BaseCloner
  include_association :tag_mappings
end

rails console

a = FactoryBot.create(:a, :with_tags)
a.tag_mappings # => <TagMapping owner_id: 1, owner_type: A, tag_id: 1>
a.tags # => <Tag id: 1>
cloned_a = ACloner.call(a).to_record
cloned_a.tags # => []
cloned_a.tag_mappings # => <TagMapping owner_id: nil, owner_type: A, tag_id: 1>

My workaround is:

class ACloner < Common::BaseCloner
  finalize do |original_a, cloned_a, _params| do
    cloned_a.tags = original_a.tags
  end
end

Thank you :-)

Hey!
Can you try to load tags from a persisted record, please?

a = FactoryBot.create(:a, :with_tags)
a.tag_mappings # => <TagMapping owner_id: 1, owner_type: A, tag_id: 1>
a.tags # => <Tag id: 1>
operation = ACloner.call(a)
operation.persist # => true

cloned_a = operation.to_record.reload

cloned_a.tags # => ?
cloned_a.tag_mappings # => ?

Thank @ssnickolay for your super fast response and solution. It works perfectly!