我正在使用friendly_id向我的模型及其相应的url添加自定义块。目前,我有一个Post
属于Board
的设置。毫无疑问,在某些情况下,某个职位的标题与另一个职位相同,但董事会成员不同。通常,我注意到网站(包括SO)在投放之前会添加一组唯一的数字,以确保不存在唯一性问题:
https://stackoverflow.com/questions/123456/my-example-question
我想知道实现这一目标的最佳方法是什么?不能仅通过路由文件来完成此操作,因为仍然存在创建两个或更多相同帖子的可能性。会改变我的模型,路线文件和friendly_id gem的配置吗?
我的最终目标是为我的帖子生成一个这样的网址:
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
答案 0 :(得分:1)
您可以在路线中执行以下操作:
resources :boards do
resources :posts, path: ':board_real_id'
end
并将params[:board_real_id]
添加到您的查询中。
我认为您不需要为此的UUID(除非您愿意)。您可以使用candidates
,如果两个帖子具有相同的名称,并且它们属于同一板,只需插入帖子的ID,就可以了,您将得到类似https://example.com/boards/example-board/123456-example-post
发件人:http://norman.github.io/friendly_id/file.Guide.html
由于UUID丑陋,因此FriendlyId提供了“子弹候选” 功能,可让您指定在事件中使用的备用弹头 您要使用的已被使用。例如:
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
答案 1 :(得分:0)
您需要使用slug_candidates
,请参阅文档here。
在您的情况下,您所需要的只是在子段的末尾/开头添加一个uuid,您可以使用增量uuid来实现。如果您有当前子弹的记录,请获取最大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
我正在使用MYSQL语法来匹配正则表达式模式。