友好的 ID slug 不包含 id
Friendly ID slug does not contain the id
我想要 url 这样的:
http://domain.com/products/454-table-lamp
所以我这样使用 friendly_id:
extend FriendlyId
friendly_id :slug_candidates, use: :history
def slug_candidates
[
[:id, :title]
]
end
现在,由于友好的 id 在对象被保存之前生成了 slug,所以我最终得到一个 url 像这样(请注意 URL 中缺少的 id):
http://domain.com/products/table-lamp
虽然这还不算太糟糕。一旦我保存了另一个名为 "Table Lamp" 的产品,我将得到一个 URL,如下所示:
http://domain.com/products/table-lamp-ebaf4bf5-a6fb-4824-9a07-bdda34f56973
所以我的问题是,如何确保友好 ID 也创建包含该 ID 的 slug。
好吧,简短的回答 - 你不能。 FrienlydId 在此处的 before_validation
回调中生成 slug:https://git.io/vgn89。问题是您需要在保存之前生成 slug 以避免冲突,但是您想要使用只有在实际保存之后才可用的信息,当记录已经在数据库中时。
看看这个answer for details。
当然,如果你真的想要的话,你可以这样做:
def slug_candidates
[ title, Model.maximum(:id) + 1 ]
end
但是这段代码不是线程安全的,可能会导致一些明显的问题。另一种方法 - 在保存后更改 slug,例如在 after_create
回调中。您可以将其设置为 nil
并再次调用 set_slug
。
但问问自己 - 你真的需要它吗?可能最好使用 created_at 中的时间戳作为 slug 候选的一部分?
只需向您的模型添加一个 after_commit 回调。在此回调中,将 slug 设置为 nil 并保存:
after_commit :update_slug, on: :create
def update_slug
unless slug.include? self.id.to_s
self.slug = nil
self.save
end
end
我想要 url 这样的:
http://domain.com/products/454-table-lamp
所以我这样使用 friendly_id:
extend FriendlyId
friendly_id :slug_candidates, use: :history
def slug_candidates
[
[:id, :title]
]
end
现在,由于友好的 id 在对象被保存之前生成了 slug,所以我最终得到一个 url 像这样(请注意 URL 中缺少的 id):
http://domain.com/products/table-lamp
虽然这还不算太糟糕。一旦我保存了另一个名为 "Table Lamp" 的产品,我将得到一个 URL,如下所示:
http://domain.com/products/table-lamp-ebaf4bf5-a6fb-4824-9a07-bdda34f56973
所以我的问题是,如何确保友好 ID 也创建包含该 ID 的 slug。
好吧,简短的回答 - 你不能。 FrienlydId 在此处的 before_validation
回调中生成 slug:https://git.io/vgn89。问题是您需要在保存之前生成 slug 以避免冲突,但是您想要使用只有在实际保存之后才可用的信息,当记录已经在数据库中时。
看看这个answer for details。
当然,如果你真的想要的话,你可以这样做:
def slug_candidates
[ title, Model.maximum(:id) + 1 ]
end
但是这段代码不是线程安全的,可能会导致一些明显的问题。另一种方法 - 在保存后更改 slug,例如在 after_create
回调中。您可以将其设置为 nil
并再次调用 set_slug
。
但问问自己 - 你真的需要它吗?可能最好使用 created_at 中的时间戳作为 slug 候选的一部分?
只需向您的模型添加一个 after_commit 回调。在此回调中,将 slug 设置为 nil 并保存:
after_commit :update_slug, on: :create
def update_slug
unless slug.include? self.id.to_s
self.slug = nil
self.save
end
end