在路由前添加一个 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.
我正在使用 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.