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.

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.

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?

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

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.