2013-04-09 36 views
1

我正在爲after_create回調創建郵件的slu and,並且我不知道如果在slu already已經存在的情況下如何在末尾附加數字。添加一個數字到title.parameterize來通過唯一性驗證

class Post < ActiveRecord::Base 
    attr_accessible :body, :title, :slug 
    after_create :create_slug 
    validates_uniqueness_of :slug 

    def create_slug 
    existing = Post.where("slug LIKE ?", "#{title.parameterize}%").length 
    existing > 0 ? slug = "#{title.parameterize}-#{existing+1}" : slug = title.parameterize 
    self.update_attributes(slug: slug) 
    end 
end 

這不工作,因爲我where條款,標題爲「一些稱號那就不同了」,例如職位相匹配。

一種解決方案是追加post.id而不是嘗試枚舉。這在刪除帖子的情況下也可能更好。但我不希望刪除任何帖子,並且不使用ID似乎更有意義。

有什麼建議嗎?

回答

1

Post.where(title: title).count 

給你在你的情況是否正確?

重要的是還要在DB中的slug列上設置一個唯一約束,因爲如果在相似時間創建了兩個具有相同標題的帖子,則該算法會受到競爭條件的影響。 Rails本身不能保證列的唯一性。

+0

我之所以懷疑使用它的原因是因爲,例如''一些標題:等等。「.parameterize'返回與'」某些標題和更多「.parameterize'相同的子彈。所以比較標題並不總是會通過唯一性驗證。 (編輯問題以將其添加到) – mehulkar 2013-04-10 04:52:44

+0

將程序段包裝在開始/救援中,並且如果您捕獲唯一性異常,則將後綴加1並再試一次。追加post.id是一種常見的模式,所以使用url blahblah-1234時,控制器實際上做了params [:slug] .split(' - ')。最後得到Post ID,但該URL對於Google來說仍然很不錯和用戶。例如。 http://theconversation.com上的任何文章 – 2013-04-10 06:18:39

+0

嗯,我想我可以做db ID併爲現有的帖子運行rake任務。雖然不是開始/救援想法的粉絲,但不知道爲什麼。 – mehulkar 2013-04-11 03:39:48