Rails4 Friendly_id独特的Slug格式

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-1explore-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调用中保存对象是否危险?可能,但它似乎对我有用.


x3m*_*mka 9

同意,这似乎是非常粗暴的行为.

如果你看代码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)

所以,这个想法只是为了修补它.我看到两个选项:

  1. 只需修补resolve_friendly_id_conflict,添加随机后缀.

  2. 改变两种方法的逻辑,意图尝试所有候选人,直到slug_generator.generate(candidates)返回非空的东西.如果所有候选人都给予nil后退resolve_friendly_id_conflict方法.使用这种技术,你可以使用slug候选者id在slug不唯一时附加模型.

理想情况下,如果gem的作者添加了一个配置选项来处理独特的slugs解析(方法符号或proc将生成器和候选者作为params)或者只是检查模型是否响应某种方法,那将是很好的.

此外,在一些使用案例中,根本不需要独特的段塞分辨率.例如,如果我们只想依靠validates_uniqueness_of :slug候选人的唯一性验证.

  • 只需创建一个像“Friendly_id.rb”这样的初始化程序,如下所示: moduleFriendlyId moduleSluggeddefresolve_Friendly_id_conflict(candidates)my_cool_unique_suffix=...candidates.first+Friendly_id_config.sequence_separator+my_cool_unique_suffixendendend (2认同)
  • http://pastebin.com/rz2VHLFZ您可以阅读有关猴子修补的更多信息:http://www.runtime-era.com/2012/12/reopen-and-modify-ruby-classes-monkey.html但是不要虐待猴子补丁.一旦你需要很多改变,最好分叉一个宝石. (2认同)

tir*_*adc 7

: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)