I'm not 100% sure about why ActiveModel::Dirty
has its name. I'm guessing it is because it is considered as dirty to use it.
But in some cases, it is not possible to avoid watching on specific fields.
Ex:
if self.name_changed?
self.slug = self.name.parameterize
end
Without ActiveModel::Dirty
, the code would look like:
if old_name != self.name
self.slug = self.name.parameterize
end
which implies having stored old_name
before, and it is not readable, so IMHO, it is dirtier than using ActiveModel::Dirty
. It becomes even worse if old_number
is a number and equals params[:user]['old_number']
as it needs to be correctly formated (parsed as int), whereas ActiveRecord does this automagically.
So I would find clean to define watchable fields at Model level:
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
Or (even better?) at controller level, before assigning new values:
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
The good thing here is that it removes the memory overload produced by using ActiveModel::Dirty
.
So my question is:
Can I do that using ActiveRecord pre-built tools, or should I write a custom library to this?
Thanks