在路由前添加一个 UUID 以确保 slug 的唯一性

Prepending a UUID to route to ensure uniqueness of slug

我正在使用 friendly_id 向我的模型及其相应的 url 添加自定义 slug。目前我有一个 Post 属于 Board 的设置。毫无疑问,在某些情况下,post 将与另一个人拥有相同的标题,但来自不同的董事会。我经常注意到网站(包括在内)在 slug 之前添加了一组唯一的数字,以确保没有唯一性问题:


我想知道完成此任务的最佳方法是什么?这不能仅通过路由文件来完成,因为仍然存在创建两个或更多相同 post 的可能性。它会是更改我的模型、路由文件和 friendly_id gem 配置的组合吗?

我的最终目标是为我的 post 生成这样的 url:

https://example.com/boards/example-board/123456/example-post

class Board < ApplicationRecord
  extend FriendlyId

  has_many :posts

  friendly_id :name, use: :slugged
end


class Post < ApplicationRecord
  extend FriendlyId

  belongs_to :board

  friendly_id :title, use: :slugged
end

resources :boards do
  scope module: :boards do
    resources :posts
  end
end

编辑

你可以在你的路线中做这样的事情:

resources :boards do
  resources :posts, path: ':board_real_id'
end

并将 params[:board_real_id] 添加到您的查询中。

我认为您不需要 UUID(除非您愿意)。您可以使用 candidates 并且如果两个 post 具有相同的名称并且它们属于同一个板,只需插入 post 的 id 就可以了,您将有类似 https://example.com/boards/example-board/123456-example-post

的东西

发件人:http://norman.github.io/friendly_id/file.Guide.html

Since UUIDs are ugly, FriendlyId provides a "slug candidates" functionality to let you specify alternate slugs to use in the event the one you want to use is already taken. For example:

friendly_id :slug_candidates, use: :slugged

  # Try building a slug based on the following fields in
  # increasing order of specificity.
  def slug_candidates
    [
      :name,
      [:id, :name]
    ]
  end

您需要使用 slug_candidates,请参阅文档 here

在你的情况下,你只需要在 slug 的 end/start 中添加一个 uuid,你可以通过使用增量 uuid 来实现。如果你有当前 slug 的 a 记录,获取最大 uuid 并将其增加 1,保存!

class Post < ApplicationRecord
  extend FriendlyId

  belongs_to :board

  friendly_id :slug_candidates, use: :slugged


  def slug_url
    name
  end

  def slug_candidates
    [:slug_url, [:slug_url, :slug_uuid]]
  end

  def slug_uuid
    result = Post.select("COUNT(REGEXP_SUBSTR(name, '[0-9]+$')) AS cnt, MAX(REGEXP_SUBSTR(title, '[0-9]+$')) + 1 AS mx_uuid")
    result.cnt == 0 ? "" : result.mx_uuid + 1
  end
end

I am using MYSQL syntax to match the regex pattern.