Search code examples
ruby-on-railsrubyoopmodelhelper

Rails checking model to see if all fields are empty


As far as I've tested it, this helper method works exactly as it's meant to, however I want to know if there is any easier, built-in, or smarter way to run this check! I also am aware that having this in the ApplicationHelper probably isn't ideal. Not sure if I should just put it in the parent object (the Inspection), some other model, or leave as is.

With is_model_empty? I need to run through every field of any one of eleven different (but similar) models to check to see if all of them are Empty. All of them except the :id, :inspection_id, :created_at, and :updated_at fields which will never be blank. Empty can be nil, can be [], or can be ['']. An empty string would actually imply that the user entered something so that won't be included. The value can be either a string or an array so .empty? won't work.

def is_model_empty?(model)
    model.attributes.each do |k, v|
        unless ['id', 'inspection_id', 'created_at', 'updated_at'].include?(k)
            return false unless v.nil? || v == [] || v == [""]
        end
    end
    true
end

The eleven models all belong to the Inspection and each has a has_one relationship:

has_one :first_info_section
has_one :second_info_section
has_one :third_info_section

Any advice/feedback would be much appreciated. Thanks for reading!

-Dave


Solution

  • Your method can be simplifed as an instance method on each of the models. If the attribute exceptions are the same for all the models you can create a shared library and include it each of the models.

    app/models/empty_detection.rb:

    module EmptyDetection
      def empty?
        attributes.all? do |k, v|
          ['id', 'inspection_id', 'created_at', 'updated_at'].include?(k) || v.nil? || v == [] || v == [""]
        end
      end
    end
    

    Include that module in each model you want to be able to check for the empty conditions. For example, the Widget model:

    class Widget < ActiveRecord::Base
      include EmptyDetection
    end
    

    Now you can use it on any instance of a Widget:

    widget = Widget.find(45)
    widget.empty?