Friendly_id为Rails中的多个对象创建重复的slug

时间:2015-08-04 04:09:13

标签: ruby-on-rails ruby-on-rails-4 friendly-id

我的Rails版本不包含路径名。该应用程序包含两个主要对象:collectionsitems。因此,如果我有一个链接:https://foo.com/foo,这可能会识别集合或项目。在整个应用程序的上下文和UI流程中明确区别。

我的问题:有没有办法让Friendly ID gem通过查看slug是否已被另一个对象占用来生成独特的slug?我知道您可以生成候选项,以便友好ID不会复制给定对象的slug,但我需要友好的ID来检查现有的集合slug和项目slug,然后再生成一个新的slug。

我希望这听起来不会太混乱。要更简洁地重新说明:在生成新的slug之前,是否有一种方法可用于友好ID来检查多个对象中的slug?

1 个答案:

答案 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