Comparing polymorphic property to same object fails

I’ve got a polymorphic association on one table. I assign to it in the
controller.

This is handling invitations of users to tasks in a task management
application. If the user issuing the invitation is the user being
invited (ie the user assigned themselves to a task), I want to
activate the invitation immediately in the model.

The trouble is that this:

if self.assignable == self.created_by
  self.activated_at = Time.now
  self.activation_code = nil
end

fails to detect equality correctly. I’ve tried ===, eql? etc.

When I look at .id when I know that I set assignable equal to
created_by, the values are different (wildly so; one is like 4 and the
other is a five digit number or something).

I’m guessing Rails handles polymorphic associations via a proxy object
or something. So the question is: how do I do this comparison?

You can get the underlying object from the proxy calling #target or
#proxy_target. That should allow you to compare the object ids
directly.

But why not compare the #id (eg, the actual primary key of the users
table) of both assignable and created_by. This is safer especially if
activerecord decides load created_by and assignable into two different
objects which is probably very likely.

On May 6, 9:54 am, eden li [email protected] wrote:

You can get the underlying object from the proxy calling #target or
#proxy_target. That should allow you to compare the object ids
directly.

But why not compare the #id (eg, the actual primary key of the users
table) of both assignable and created_by. This is safer especially if
activerecord decides load created_by and assignable into two different
objects which is probably very likely.

The problem with comparing just the ids is if the polymorphic
association is to a different table (ie to a different class), to an
object that happens to have the same id in that other table.

Unfortunate that if this is documented anywhere, it’s carefully
hidden. :frowning:

Thanks.

On May 6, 9:54 am, eden li [email protected] wrote:

You can get the underlying object from the proxy calling #target or
#proxy_target. That should allow you to compare the object ids
directly.

This doesn’t work. Changing the code to:

if self.assignable.target == self.created_by
  self.activated_at = Time.now
  self.activation_code = nil
end

fails. As does using assignable.proxy_target.

Anyone know how to get this working?

On May 6, 5:46 pm, Gisborne [email protected] wrote:

  self.activation_code = nil
end

fails. As does using assignable.proxy_target.

Anyone know how to get this working?

Whoops. Turns out it works fine and I was just being a complete moron.
Thanks for the help.

On May 7, 12:44 am, Gisborne [email protected] wrote:

The problem with comparing just the ids is if the polymorphic
association is to a different table (ie to a different class), to an
object that happens to have the same id in that other table.

Maybe I misunderstand your schema, but after retrieving “assignable”
you should get a proper user object. The polymorphic association will
retrieve the object from the right table for you. This is one of the
reasons you need an :assignable_type column.

Unfortunate that if this is documented anywhere, it’s carefully
hidden. :frowning:

The association proxies are in the guts of ActiveRecord. I assume
it’s not well documented because rails-core wants to be able to make
massive changes to it between releases. Anyway, you only need to deal
with them if you’re relying on strict ruby object semantics.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs