-
-
Notifications
You must be signed in to change notification settings - Fork 592
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
STI test failure when looking up record from SubClass #516
Conversation
Thanks for this.. my first impression is that somewhere we're not referencing the |
Got a little closer just now.
|
Oh, right, no that's totally expected.. FriendlyId scopes don't apply unless you use |
Well the reason I came across this is because of what I have in my code: class Product < ActiveRecord::Base
extend FriendlyId
friendly_id :name, :use => [:slugged, :finders]
end
class GiftCard < Product
end
gift_card = GiftCard.create name: "foo"
GiftCard.find gift_card.slug #=> AR::NotFound So the finders module is not being inherited to the subclass. Is that intentional? |
Your example code and test case didn't specifically include the I don't think that the module should automatically inherit to the subclass... @norman what do you think? |
Changes Unknown when pulling 09606c0 on ScotterC:sti-test-failure into * on norman:master*. |
I just now added the finders module to the test case. Your right. before it should have failed. But it still fails with the module added. |
Does your test case pass if you add the same friendly_id line to the subclass? |
Added. And yes it does still fail. Any ideas on why they wouldn't be inherited? It's the same extension of class methods in the finders module no? |
Changes Unknown when pulling 2d7fba5 on ScotterC:sti-test-failure into * on norman:master*. |
Changes Unknown when pulling 2d7fba5 on ScotterC:sti-test-failure into * on norman:master*. |
relation_class_name = :"#{klass.to_s.gsub('::', '_')}_#{self.to_s.gsub('::', '_')}" | ||
klass.const_get(relation_class_name) | ||
end | ||
def relation_delegate_class(klass) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was just a spacing issue. nothing changed.
Cleaned up the PR so it doesn't overwrite the other tests. The finder methods are just not being included in the sub classes. From what I can tell, This is because the extension of the class returns if it responds to friendly_id and therefore the configuration is not initialized and finder_methods are not included. I see two approaches depending on what the core team wants. Have the finder methods get inherited to sub classes if they are included in the parent or change the |
Changes Unknown when pulling 910cdc9 on ScotterC:sti-test-failure into * on norman:master*. |
adding finders to both cleaned up test sub class of STI can't create records if parent does not extend friendly id
Changes Unknown when pulling d957e8e on ScotterC:sti-test-failure into * on norman:master*. |
Any news on this one ? I got the same exact problem. Any workarounds to not have to use GiftCard.friendly.find 'slug' ? |
That's my current workaround. With 5.0 it seems that the core wants finder methods to be optional. However, the design of finder methods getting included into each subclass seems a bit tricky. I can't figure out why they're in the model's ancestors but the methods aren't included. |
I'm seeing this too, in rails 4.0.2 and friendly_id 5.0.2. Changing my app to use |
I have the same problem as @jaredbeck. Luckily, we have a module encapsulating our Slug behaviour (friendly id is the third library we use). The :finders module is switched on in an initializer. Somehow, this fixes the problem of having to use # Include Shop::Slugs in a Model to get application-wide solid slug behaviour
#
# Please define #to_slug on your model, so that this works.
module Shop
module Slugs
def self.included(model)
super
model.class_eval do
extend FriendlyId
friendly_id :to_slug, :use => [:history]
extend Inheriting
end
end
# friendly_id keeps a config per class, but does not inherit the :finders
# module, so we have to re-apply the settings
module Inheriting
def inherited(child)
super
child.class_eval do
include ::Shop::Slugs
end
end
end
end
end |
Sadly, my approach above causes an early DB access while booting the Rails app, because friendly_id attaches |
Checking for |
As an ugly workaround, it looks like we can put something like this in each of our child classes: class MySTIChildClass
class << MySTIChildClass
alias_method :super_find, :find
end
def self.find(*args)
friendly.super_find(*args)
end
end |
Without this change, STI classes skipped adding the finders because FriendyIdConfig#uses? would return true for FriendlyId::Finders when the parent class had this module loaded, so the module loading would always be skipped in the child module. However, since FriendId::Finders.setup is always invoked when adding a FriendlyId addon, the module will now get added to child classes. See #516
Previously, if the child class had the finder modules loaded but the parent class did not, then slugs could not be created because the slug generator assumed friendly finders were available, but were not because the scope is uses comes from the super class rather than the child class. The child class scope is not used in order to maintain slug uniqueness across child classes. See #516
@ScotterC Thanks for the work on this. I've fixed the test failures and merged your changes. This will go out in the next few minutes to Rubygems. |
Cool. From the commits it looks like you found the root of the issue. Thanks @norman |
I just tried 5.0.3. Looks like |
Shouldn't subclasses have to opt in? |
Yes, @jaredbeck, you must call friendly_id in each class. That's by design. |
That makes sense. One last thing: The documentation (http://norman.github.io/friendly_id/file.Guide.html) says:
but it doesn't mention invoking the |
You don't have to invoke friendly_id in the parent class if you're only Sent from my phone |
Also: