2014-02-06 29 views
1

我有一個子類ActiveRecord模型,它使用一個單獨的表來存儲記錄和friendly_id(4.1.0.beta.1)來生成slu。。問題是friendly_id正在使用父類的表來檢查是否存在子彈,而不是使用子表。基本上我希望friendly_id將其檢查範圍限定在正確的表格中。使friendly_id作用域與分類的ActiveRecord模型很好玩

例子:

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生成第二創建「你好」塞,因爲在與塞孩子表中沒有記錄。有沒有一種方法來配置或猴子補丁類友好的ID用於其查詢?

編輯:添加friendly_id版本以供將來參考

回答

0

我張貼我自己解決這個問題,以防萬一有人有同樣的問題。我應該重申,在friendly_id gem(當時是最新版本)版本4.1.0.beta.1上發現了此問題,因此此問題可能不再發生。

爲了解決這個問題,我基本上配置了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 
相關問題