2012-11-10 20 views
0

我想了解如何在關於處理to_parampermalinks處理永久用戶更新時固定鏈接已被使用的Rails 3.2

基本上這是發生什麼事了一些建議。

  • 創建一個新的公司
  • 公司:name然後參數,並保存在數據庫
  • 一個:permalink更新現有公司,您可以更改的:permalink
  • 有驗證,以確保用戶的更新:permalink是唯一的

我遇到的問題是當更新公司的:permalink到已經存在的東西。唯一性驗證工作,這是偉大的,但如果我嘗試編輯permalink別的東西,我得到的"Name already taken"閃存驗證錯誤,因爲它認爲它改變了params[:id]到無效的永久鏈接,而不是正在重置,並使用現有的params[:id]

的我正在編輯已有的:permalink(公司)的公司。由於我的companies_controller.rb正在使用@company = Company.find_by_permalink[:id])

我想知道處理此問題的最佳方法嗎?

class Companies < ActiveRecord::Base 
    before_create :set_permalink 
    before_update :update_permalink 

    attr_accessible :name, :permalink 

    validates :name, :permalink, uniqueness: { message: 'already taken' } 

    def to_param 
    permalink 
    end 

    private 

    def set_permalink_url 
    self.permalink = name.parameterize 
    end 

    def update_permalink_url 
    self.permalink = permalink.parameterize 
    end 


end 

道歉,如果我沒有太多的意義。

在此先感謝。

回答

0

你可以試着用after_rollback回調來解決這個問題。

after_rollback :restore_permalink 

def restore_permalink 
    self.permalink = permalink_was if permalink_changed? 
end 

下面是它的工作原理:Rails中的每個更新/銷燬都包含在一個事務中。如果保存失敗,事務將回滾並觸發回調。 如果自從記錄加載後發生更改,則回調將恢復舊值(permalink_was)。

有關更多信息,請參閱ActiveModel::DirtyActiveRecord::Transactions

編輯

在另一方面,可能是另一種解決方案(未經測試) - 只是這樣定義您的訪問:

def permalink=(value) 
    permalink_will_change! unless @permalink == value 
    @permalink = value 
end 

這樣,永久不會被標記如果新值與舊值相同,則爲髒,因此AR不會嘗試更新列。

說明:

我不知道它是實現軌的版本(這是比較近),但這裏的「dirtyness」是如何工作的:

  • 你的「標準」 (自動地產生的)屬性設置器將相關的 實例變量(即使設置比以前的值完全相同)
  • 當調用之前basicly調用 ,ActiveRecords查找已更改的屬性(「髒」),並僅使用這些屬性構建SQL UPDATE查詢(主要是出於性能原因)
  • 所以如果要避免在查詢中出現永久鏈接不變,我認爲你必須重寫標準制定者 - 或者避免大規模分配,如果它已經改變,只設置permalink
+0

嗨m_x,謝謝你花時間和解釋各種概念。非常感謝,謝謝。我只是遇到了after_rollback回調問題,因爲它仍然在改變url(永久鏈接)而不是恢復到permalink_was。因此,不是使用現有的id,而是將id更改爲不同的公司(例如用戶試圖更改的已存在的profile_url)。 –

+0

嗯...我的不好。我認爲我給你的第二個解決方案應該更好(刪除回調) –

+0

再次感謝M_x。是否有可能更深入地瞭解第二種解決方案的工作原理。我完全相信如何實現它。感謝你的幫助。 –