我的Rails版本不包含路径名。该应用程序包含两个主要对象:collections
和items
。因此,如果我有一个链接:https://foo.com/foo,这可能会识别集合或项目。在整个应用程序的上下文和UI流程中明确区别。
我的问题:有没有办法让Friendly ID gem通过查看slug是否已被另一个对象占用来生成独特的slug?我知道您可以生成候选项,以便友好ID不会复制给定对象的slug,但我需要友好的ID来检查现有的集合slug和项目slug,然后再生成一个新的slug。
我希望这听起来不会太混乱。要更简洁地重新说明:在生成新的slug之前,是否有一种方法可用于友好ID来检查多个对象中的slug?
答案 0 :(得分:3)
注意这些都是未经测试的,只需使用文档并阅读源代码即可。
您可以继承 FriendlyId :: SlugGenerator 类,并覆盖可用?方法以检查对方模型中的现有记录:
class CrossModelSlugGenerator << FriendlyId::SlugGenerator
def available?(slug)
if (@scope.class == "Item::ActiveRecord_Relation")
# Search for collections with this slug and return false if they exist.
elsif (@scope.class == "Collection::ActiveRecord_Relation")
# Search for items with the this slug and return false if they exist.
end
# Otherwise do a normal slug check
!@scope.exists_by_friendly_id?(slug)
end
end
您可以在此处查看SlugGenerator类的完整代码:
https://github.com/norman/friendly_id/blob/master/lib/friendly_id/slug_generator.rb
然后,您必须告诉Friendly ID配置使用该类。在 config / intitializers / friendly_id.rb 中创建初始化程序:
FriendlyId.defaults do |config|
config.slug_generator_class = "CrossModelSlugGenerator"
end
尝试一下,看看它是否适合您。再说一次,我还没有对它进行测试,但似乎它应该可以解决。
编辑 - 您可能需要将此类包装在FriendlyId模块中,如下所示:
您可能需要在某处包含,可能在您的类定义中。另外,尝试将类包装到FriendlyId模块中,所以可能是这样的:
include "friendly_id"
module FriendlyId
class CrossModelSlugGenerator << SlugGenerator
...
end
end
通过此更改,您可能还需要在配置类名称中明确指定模块:
FriendlyId.defaults do |config|
config.slug_generator_class = "FriendlyId::CrossModelSlugGenerator"
end