【问题标题】:Friendly_id creating duplicate slugs for multiple objects in RailsFriendly_id 在 Rails 中为多个对象创建重复的 slug
【发布时间】:2015-10-26 08:13:18
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

    注意这一切都未经测试,只是从文档中工作并阅读源代码。

    您可以继承 FriendlyId::SlugGenerator 类,并重写 available? 方法以检查对立模型中的现有记录:

    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

    然后您必须告诉友好 ID 配置来使用该类。在config/initializers/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
    

    【讨论】:

    • 这看起来很有希望,我明天早上第一件事会检查这个并回复你。谢谢乔科!!
    • 不幸的是,我的应用程序无法找到“slug_generator_class”。不知道为什么这是一个问题,我使用的是 gem 的 5.1.0 版本,并且确实在我的模型中使用了“slugged”:extend FriendlyId friendly_id :slug_candidates, use: [:slugged, :finders]
    • 用方法中的一些变化更新了原始答案,看看它们是否适合你。
    • 你摇滚!看起来可能有几种方法可以做到这一点,但你的方法效果很好。我还尝试添加各种 slug 候选对象和 if 条件,以在为给定集合选择新 slug 之前先查看我的项目标题。非常感谢您的知情和有益的回答!
    • slug_generator_class 抛出 undefined method 并使用 CrossModelSlugGenerator 抛出 undefined method new for CrossModelSlugGenerator:(
    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 2012-09-30
    • 2014-08-20
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 2015-02-12
    相关资源
    最近更新 更多