thanks!

FWIW, all my class names are actually passed around as strings

On Monday, November 15, 2021 at 3:37:18 PM UTC-5 Jeremy Evans wrote:

> On Mon, Nov 15, 2021 at 11:50 AM Benjamin Hutton <benh...@gmail.com> 
> wrote:
>
>> Hey Jeremy,
>>
>> I am seeing some strange behavior with many_to_many associations, 
>> association cloning, and classes.
>>
>> I am building a set of sequel models to interact with a legacy database 
>> that we are slowly migrating away from, and trying to untangle some 
>> polymorphism in the old database.
>>
>> I started with a bunch of associations like the following:
>>
>> many_to_many :audios, class: 'Legacy::Models::SequelAudio', join_table: 
>> :content_syndications, left_key: :contentable_id, right_key: :content_id 
>> do |ds|
>>    ds.where(:contents[:type] => 'Contents::Audio')
>> end
>>
>> I then realized that I can do the following, in order to get rid of the 
>> block on the association:
>>
>> class Legacy::Models::SequelAudio < Legacy::Models::SequelContent
>>   set_dataset LEGACY_DB[:contents].where(type: 'Contents::Audio')
>> end
>>
>> Which leads to:
>>
>> many_to_many :audios, class: 'Legacy::Models::SequelAudio', join_table: 
>> :content_syndications, left_key: :contentable_id, right_key: :content_id
>>
>> At this point, I realize I am relying on something cool going on with the 
>> class argument.
>>
>> I then try to further DRY up my code by doing this:
>>
>> many_to_many :audios, clone: :contents, class: 
>> 'Legacy::Models::SequelAudio'
>>
>> Unfortunately, it seems like the class that I am specifying is no longer 
>> getting applied. The association returns records with the class that is 
>> on the cloned contents association, not the audios association. And it 
>> isn't using the correct dataset anymore.
>>
>> Is there something else that I need to be doing? Am I misunderstanding 
>> cloning?
>>
>
> I had trouble reproducing the example at first, using the following code:
>
>  A = Class.new(Sequel::Model)
> Content = Class.new(Sequel::Model(:contents))
> Audio = Class.new(Sequel::Model(DB[:contents].where(:type=>'audio') ))
> A.many_to_many :contents, :class=>Content, :join_table=>:x
> A.many_to_many :audios, :clone=>:contents, :class=>Audio
> DB.fetch = {:id=>2}
> p A.association_reflection(:contents).associated_class
> p A.association_reflection(:audios).associated_class
> p A.load(:id=>1).contents_dataset.sql
> p A.load(:id=>1).audios_dataset.sql
> p A.load(:id=>1).contents.first
> p A.load(:id=>1).audios.first
>
> The output from that is:
>
> Content
> Audio
> "SELECT contents.* FROM contents INNER JOIN x ON (x.content_id = 
> contents.id) WHERE (x.a_id = 1)"
> "SELECT contents.* FROM contents INNER JOIN x ON (x.audio_id = contents.id) 
> WHERE ((type = 'audio') AND (x.a_id = 1))"
> #<Content @values={:id=>2}>
> #<Audio @values={:id=>2}>
>
> However, I was able to reproduce this when using a symbol to the :class 
> option:
>
> A.many_to_many :contents, :class=>:Content, :join_table=>:x
> A.many_to_many :audios, :clone=>:contents, :class=>:Audio
>
> With that change, the output is:
>
> Content
> Content
> "SELECT contents.* FROM contents INNER JOIN x ON (x.content_id = 
> contents.id) WHERE (x.a_id = 1)"
> "SELECT contents.* FROM contents INNER JOIN x ON (x.audio_id = contents.id) 
> WHERE (x.a_id = 1)"
> #<Content @values={:id=>2}>
> #<Content @values={:id=>2}>
>
> So this is definitely a bug, and it's related to the late binding of 
> classes by using a string or symbol, probably because the :class option is 
> renamed to :class_name in that case, but the cloning code doesn't handle 
> that.  I'll work on a fix for it shortly.
>
> Thanks,
> Jeremy
>

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sequel-talk+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sequel-talk/ce3834da-8adf-4438-b624-686c9f15d13en%40googlegroups.com.

Reply via email to