Har*_*M V 8 rubygems ruby-on-rails friendly-id ruby-on-rails-4
我正在使用friendly_id gem来阻止我的模型.因为当我输入相同的数据来检查时,slug必须是唯一的,我会在slug中附加一个长的哈希值.
Explore explore
Explore explore-7a8411ac-5af5-41a3-ab08-d32387679f2b
Run Code Online (Sandbox Code Playgroud)
有没有办法告诉friendly_id提供更好的格式化slugs,如explore-1和explore-2
版: friendly_id 5.0.4
use*_*913 10
因此,如果有人在某些时候遇到过这种情况,我会更新我希望在tirdadc的评论中作为评论,但我不能(没有足够的声誉).所以,你走了:
从理论上讲,Tirdadc的答案是完美的,但不幸的是,在调用slug_candidates时,还没有分配对象的id,所以你需要做一些小技巧.这是获取具有该对象的id的slug的完整方法:
class YourModel < ActiveRecord::Base
extend FriendlyId
friendly_id :slug_candidates, use: :slugged
after_create :remake_slug
# Try building a slug based on the following fields in
# increasing order of specificity.
def slug_candidates
[
:name,
[:name, :id],
]
end
def remake_slug
self.update_attribute(:slug, nil)
self.save!
end
#You don't necessarily need this bit, but I have it in there anyways
def should_generate_new_friendly_id?
new_record? || self.slug.nil?
end
end
Run Code Online (Sandbox Code Playgroud)
所以你基本上是在创建对象之后设置了slug,然后在创建完对象之后,你会淘汰slug并执行一次save,这将重新分配slug(现在id完整无缺).在after_create调用中保存对象是否危险?可能,但它似乎对我有用.
同意,这似乎是非常粗暴的行为.
如果你看代码friendly_id/slugged.rb,有2个函数处理冲突解决逻辑:
def resolve_friendly_id_conflict(candidates)
candidates.first + friendly_id_config.sequence_separator + SecureRandom.uuid
end
# Sets the slug.
def set_slug(normalized_slug = nil)
if should_generate_new_friendly_id?
candidates = FriendlyId::Candidates.new(self, normalized_slug || send(friendly_id_config.base))
slug = slug_generator.generate(candidates) || resolve_friendly_id_conflict(candidates)
send "#{friendly_id_config.slug_column}=", slug
end
end
Run Code Online (Sandbox Code Playgroud)
所以,这个想法只是为了修补它.我看到两个选项:
只需修补resolve_friendly_id_conflict,添加随机后缀.
改变两种方法的逻辑,意图尝试所有候选人,直到slug_generator.generate(candidates)返回非空的东西.如果所有候选人都给予nil后退resolve_friendly_id_conflict方法.使用这种技术,你可以使用slug候选者id在slug不唯一时附加模型.
理想情况下,如果gem的作者添加了一个配置选项来处理独特的slugs解析(方法符号或proc将生成器和候选者作为params)或者只是检查模型是否响应某种方法,那将是很好的.
此外,在一些使用案例中,根本不需要独特的段塞分辨率.例如,如果我们只想依靠validates_uniqueness_of :slug候选人的唯一性验证.
:scoped如果你想在处理碰撞时避免使用slu U中的UUID,我建议使用该模块.这是文档和示例:
http://norman.github.io/friendly_id/file.Guide.html#Unique_Slugs_by_Scope
尝试使用,:scope => :id因为无论如何每个id都是唯一的,看看它是否适合你.
更新:
为了获得您想要的内容,您现在可以candidates在第5版中实现此目的:
class YourModel < ActiveRecord::Base
extend 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,
[:name, :id],
]
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4930 次 |
| 最近记录: |