2015-06-01 67 views
0

我不是100%確定爲什麼ActiveModel::Dirty有它的名字。我猜是因爲它認爲是才能使用它。ActiveModel ::髒手錶只有特定領域

但是在某些情況下,不可能避免在特定領域觀看。

例:

if self.name_changed? 
    self.slug = self.name.parameterize 
end 

沒有ActiveModel::Dirty,代碼將如下所示:

if old_name != self.name 
    self.slug = self.name.parameterize 
end 

這意味着具有前存儲old_name,並且它不可讀的,所以IMHO,它是比使用ActiveModel::Dirty。它變得更糟,如果old_number是一個數字,並且等於params[:user]['old_number'],因爲它需要正確格式化(解析爲int),而ActiveRecord自動執行此操作。

所以我會覺得乾淨定義在模型級有看頭領域:

class User < ActiveRecord::Base 
    include ActiveModel::Dirty 

    watchable_fields :name 

    before_save :generate_slug, if: name_changed? 

    def generate_slug 
    self.slug = self.name.parameterize 
    end 

end 

或(?甚至更好)在控制器級別,之前分配新值:

def update 
    @user = current_user 
    @user.watch_fields(:name) 

    @user.assign_attributes(params[:user]) 

    @user.generate_slug if @user.name_changed? 
    @user.save # etc. 
end 

好東西在這裏它可以消除使用ActiveModel::Dirty產生的內存過載。

所以我的問題是:

我能做到這一點使用ActiveRecord預建的工具,或者我應該寫一個自定義庫這樣做呢?

感謝

回答

0

下面是我最終做的事情。我喜歡它:

class User < ActiveRecord::Base 

    attr_accessor :watched 

    def field_watch(field_name) 
    self.watched ||= {} 
    self.watched[field_name] = self.send(field_name) 
    return self 
    end 

    def field_changed?(field_name) 
    self.send(field_name) != self.watched(field_name) 
    end 
end 

和Controller

def update 
    @user = current_user.field_watch(:name) 
    @user.assign_attributes(params[:user]) 
    @user.generate_slug if @user.field_changed?(:name) 
    @user.save 
end 

,如果我花時間在寶石或東西來包裝這個代碼,我會在這裏報告。

1

如果ActiveModel::Dirty解決您的問題,可隨時使用它。這個名稱來自術語「髒物」,並不意味着它是一個骯髒/黑客模塊。 查看此答案以獲取有關髒物體的更多詳細信息:What is meant by the term "dirty object"?

+0

有趣。雖然它仍然會產生內存過載,不是嗎?我的意思是,跟蹤某些領域是有道理的,但其他領域則不是。 –

+0

我確定有一些開銷,但它可能不相關,除非你有非常非常嚴格的內存要求。 – Sharagoz