我有一个用户模型的字段列表(User
belongs_toLocation
和 belongs_to Company
):
approval_fields = [:email, :location => [:first_name, :last_name], :company => [:name, :address]]
当我尝试通过此代码更新记录时,我想为用户收集所有更改:
user.update_attributes(params[:user])
我为此写了一段丑陋的代码:
# Collects changed fields and returns hash of changes:
# Example: approval_fields = [:email, :location => [:first_name, :last_name]]
# res = _collect_approval_changes(approval_fields)
# res # => {'email' => 'new_value@change.com',
# 'location_attributes' => {'first_name' => 'NewFirstName', 'last_name' => 'NewLastName'}}
def _collect_approval_changes(approval_fields)
changes = {}
approval_fields.each do |f|
if f.is_a?(Hash)
key = f.keys.first
next unless self.public_send(key) # skip this association if associated object is nil
changes["#{key}_attributes"] ||= {}
f[key].each do |v|
if self.public_send(key).public_send("#{v}_changed?")
changes["#{key}_attributes"][v.to_s] = self.public_send(key).read_attribute(v)
end
end
changes.delete("#{key}_attributes") if changes["#{key}_attributes"].blank?
else
changes[f.to_s] = self.read_attribute(f) if self.public_send("#{f}_changed?")
end
end
changes
end
你能建议如何重构这个方法吗?谢谢!