我有一个子类ActiveRecord模型,它使用一个单独的表来存储记录,而friendly_id(4.1.0.beta.1)则用于生成slug。问题是friendly_id正在使用父类的表来检查现有的slugs,而不是使用子表。基本上我希望friendly_id将其检查范围扩展到正确的表格。
示例:
class Parent
friendly_id :name, :use => :slugged
end
class Child < Parent
self.table_name = 'children'
end
Parent.create(name: 'hello').slug
> 'hello'
Child.create(name: 'hello').slug
> 'hello--2'
我希望friendly_id为第二次创建生成'hello'slug,因为子表中没有带有该slug的记录。有没有办法配置或使用类友好id用于其查询的补丁?
编辑:添加了friendly_id版本以供将来参考
答案 0 :(得分:1)
我发布了自己的解决方案,以防万一有人遇到同样的问题。我应该重申,这个问题是在4.1.0.beta.1
gem的版本friendly_id
上找到的(当时是最新版本),所以这个问题可能不再发生了。
为了解决这个问题,我基本上将slug_generator_class
配置为使用我自己的类,所以我可以修补罪魁祸首方法。
在我的模型中:
friendly_id do |config|
config.slug_generator_class = SubclassScopableSlugGenerator
end
在初始化程序中,我覆盖了FriendlyId::SlugGenerator.conflicts
方法,因此我可以访问sluggable_class
var:
# Lets a non-STI subclass of a FriendlyId parent (i.e. a subclass with its
# own dedicated table) have independent slug uniqueness.
class SubclassScopableSlugGenerator < FriendlyId::SlugGenerator
private
def conflicts
# this is the only line we're actually changing
sluggable_class = friendly_id_config.model_class
pkey = sluggable_class.primary_key
value = sluggable.send pkey
base = "#{column} = ? OR #{column} LIKE ?"
# Awful hack for SQLite3, which does not pick up '\' as the escape character without this.
base << "ESCAPE '\\'" if sluggable.connection.adapter_name =~ /sqlite/i
scope = sluggable_class.unscoped.where(base, normalized, wildcard)
scope = scope.where("#{pkey} <> ?", value) unless sluggable.new_record?
length_command = "LENGTH"
length_command = "LEN" if sluggable.connection.adapter_name =~ /sqlserver/i
scope = scope.order("#{length_command}(#{column}) DESC, #{column} DESC")
end
end