Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

polymorphic association issue with presetted "source_type" #5434

Closed
fl00r opened this issue Mar 14, 2012 · 3 comments
Closed

polymorphic association issue with presetted "source_type" #5434

fl00r opened this issue Mar 14, 2012 · 3 comments

Comments

@fl00r
Copy link

fl00r commented Mar 14, 2012

When I preset in my has_many association it's type (as a condition option) It will be rewriten if I save it in scope with root object, while if I save it separetly it will save it right.

class Foo < ActiveRecord::Base
  has_many :bars, as: :source, conditions: { source_type: "CustomType" }
end

class Bar < ActiveRecord::Base
  belongs_to :source, polymorphic: true
end

foo = Foo.new
bar = foo.bars.build
foo.bars << bar
bar.source_type
#=> "CustomType"
bar.save
bar.source_type
#=> still "CustomType"
foo.save
foo.bars.first.source_type
#=> "Foo"
@pixeltrix
Copy link
Contributor

The Bar instance that foo.bars.first returns is not the same as the one in the bar variable. If you look at the SQL generated by foo.bars.first it adds the association conditions and the polymorphic conditions as well:

SELECT "bars".* FROM "bars" WHERE "bars"."source_id" = 1 AND "bars"."source_type" = 'Foo' AND "bars"."source_type" = 'CustomType' 

I can't see how that association would ever return anything other than an empty array. This is on Rails 3.2, if by chance you are using a older version that doesn't have the commit 9c023cc (i.e 3.0) then one of the conditions overwrites the other - I can't remember which.

Perhaps the bug you're trying to demonstrate got lost in translation to abstract code?

@fl00r
Copy link
Author

fl00r commented Mar 15, 2012

Yeap, one line is missed foo.bars << bar.

It is actually not a bug. It is looks like a hack. If conventionally polymorphic associations MUST always store class name in *_type field so we need at least warn about it if someone tryies to rewrite this field. Or protect this field from straight changing.

Or. If we want to give the ability of rewriting this field, so we shouldn't rewrite it while saving parent object. I mean if we have already set field with some default value, save process shouldn't rewrite with class name, and if the field is blank, so it must write class name there.

What I mean. In first case when we protect our *_type:

foo = Foo.new
bar = foo.bars.build
bar.source_type
#=> "Foo", not "CustomType"! And warning 'You are trying to set protected polymorphic field blah blah blah. Rejected'

In second case

foo = Foo.new
bar = foo.bars.build
foo.bars << bar
foo.save
foo.bars.first.source_type
#=> "CustomType"

I think it should be protected from setting it in conditions option or elsewhere. Because it looks like how polymorphic associations works. And it will work like bar.source properly in any case :) because if we can rewrite *_type field it won't work without some additional class mapping magick

@ahawkins
Copy link

@fl00r is this closed then? Seems you've pretty much answered your own question. I think you may have just ran into an edge in polymorphic associations.

@fl00r fl00r closed this as completed Apr 29, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants