我想要这样的网址:
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。
答案 0 :(得分:7)
只需在模型中添加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
答案 1 :(得分:2)
嗯,简短的回答 - 你不能。 FrienlydId在def slug_candidates
[ title, Model.maximum(:id) + 1 ]
end
回调中生成slu :: https://git.io/vgn89。问题是你需要在保存之前生成slug以避免冲突,但是你想要使用仅在实际保存之后可用的信息,当记录已经在db中时。
当然,你可以做一些事情,如果你真的想要它:
after_create
但是这段代码不是线程安全的,可能导致一些明显的问题。另一种方法 - 例如在nil
回调中更改保存后的slug。您可以将其设置为set_slug
并再次致电meta(property='og:url', content='#{pageUrl} == '' ? 'a' : 'c'')
。
但问问自己 - 你真的需要它吗?也许最好使用created_at中的时间戳,例如作为slug候选者的一部分?