I want to implement a method that checks if a model's instance has only nil or empty attributes, except from its id or timestamps.
I've made use of an auxiliary method that removes a key from Hash开发者_开发技巧 and return the remaining hash ( question 6227600)
class ActiveRecord::Base
def blank?
self.attributes.remove("id","created_at","updated_at").reject{|attr| self[attr].blank?}.empty?
end
end
I guess that there may be much simpler, efficient or safer way to do this. Any suggestion?
def blank?
self.attributes.all?{|k,v| v.blank? || %w(id created_at updated_at).include?(k)}
end
My response is almost the same that tadman gave, but expressed in a more concise way. Be careful with two situations:
- **blank?** is not a good choice as name, since if you call **object_a.object_b.blank?** trying to know if there is or not a object_b inside object_a, you'll get true event if the object exists. **empty?** seems a better name
- If databases sets defaults values, it can be tricky.
EDIT: Since build an array every iteration is slow (thanks tadman), a beter solution is:
def empty?
ignored_attrs = {'id' => 1, 'created_at' => 1, 'updated_at' => 1}
self.attributes.all?{|k,v| v.blank? || ignored_attrs[k]}
end
You could just check that all the properties in the attributes
hash are not present, or the converse:
class ActiveRecord::Base
def blank?
!self.attributes.find do |key, value|
case (key)
when 'id', 'created_at', 'updated_at'
false
else
value.present?
end
end
end
end
Unfortunately this will not account for things that are set with a default
in your database, if any relationship keys are assigned, among other things. You will have to add those as exceptions, or compare the values to a known default state of some sort.
This sort of thing is probably best implemented on a case by case basis.
精彩评论