-
Notifications
You must be signed in to change notification settings - Fork 86
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
is_a? Confuses association consistency #49
Comments
Maybe override |
Maybe it's better to not override |
But this gem has been overriding Another alternative I can think of is to make sure every subclass has the exact same ID as the parent class, but I think that might require more hacking to AR than it's worth. |
Also, in README:
That does not actually work, because the pen#id is not the same as product#id, which I guess is what this issue is about... |
I've recently run into what I believe to be the consequences of this... # app/models/subscription.rb
class Subscription
belongs_to :subscription_plan
end # app/models/subscription_plan.rb
class SubscriptionPlan
actable
end # app/models/subscription_plans/subscription_plan_a.rb
class SubscriptionPlans::SubscriptionPlanA
acts_as :subscription_plan
end # app/models/subscription_plans/subscription_plan_b.rb
class SubscriptionPlans::SubscriptionPlanB
acts_as :subscription_plan
end subscription = Subscription.new
plan_a = SubscriptionPlanA.new
subscription.subscription_plan = plan_a
subscription.save
plan_a.acting_as.id # => 1
subscription.subscription_plan_id # => 1
plan_b = SubscriptionPlanB.new
subscription.subscription_plan = plan_b
subscription.save
plan_b.acting_as.id # => 2
subscription.subscription_plan_id # => 1 (!!) I'm currently looking at monkey patching AR to have it automatically convert any subclass to it's # config/initializers/actable_belongs_to.rb
# Fixes issues when an acts_as subclass is assigned to a belongs_to relation
module ActableBelongsTo
def replace(record)
if record.respond_to?(:acting_as)
super(record.acting_as)
else
super
end
end
end
ActiveRecord::Associations::BelongsToAssociation.prepend ActableBelongsTo |
Yup, looks like what bit me. I think that might work for a belongs_to relation, but doesn't solve the general case where we have a has_many relation that links to an actable table. |
What about changing primary key on acting_as models? After that |
That could work, but I think that would make handling the acting_as models harder to manipulate, since almost all code assumes A more drastic change is to flip the association to be a belongs_to on the actable. This could be a step towards multi-level multi-table inheritance, i.e. C inherits from B which inherits from A, A only stores the type of C, the ID for A B and C are all the same. I don't think this is currently possible with the current ActsAs gem, makes all of them interchangeable (expected from inheritance, and we get to keep overriding That could even allow us at some point to even use normal Ruby inheritance, just throwing out a wild idea. (if anything, trying to debug both acts_as_relation and AR::acts_as has really improved my metaprogramming-fu 😛) |
AR checks that when assigning a variable to a relation (has_many/has_one) that the type of the variable assigned is consistent with the association. ActsAs overrides is_a?, which confuses this check. Anything that acts as the base type would be added, which could potentially give the wrong ID (since the ancestor ID and subclass ID are different)
I'm not sure what's a good fix for this, just sounding it out.
The text was updated successfully, but these errors were encountered: