Me
Blog about Ruby, Rails, and more!

Using class_eval to dynamically define predicate methods

2017-07-11

A predicate method ends with ?, and returns true or false

This post will be part one of a two part series about dynamically defining predicate methods with classeval and definemethod.

Often times in a Rails application, you end up storing state in your database. This state usually takes the form ofsome type of status attribute on a model. You end up needing to determine what state a specific instance of that model is in, which is a great use case for class_eval.

For example, if you have a model named User with four possible statuses you could use class_eval in the following manner:


class User
  POSSIBLE_STATUSES = %w(Active Inactive Disabled Banned)

  attr_accessor :status

  def initialize
    @status = 'Inactive'
  end

  POSSIBLE_STATUSES.each do |status|
    class_eval <<-CODE
      def #{status.downcase}?
        self.status == '#{status}'
      end
    CODE
  end
end

This will dynamically define boolean methods on the User class. To test this code, just paste it into an irb session.

You can call the status method on a new user to see the default status, which we set in the initialize method:


irb(main):001:0> User.new.status
=> "Inactive"

Finally, lets test all of our boolean method. There will be one boolean method defined for each status within our POSSIBLE_STATUSES array.


irb(main):001:0> User.new.active?
=> false
irb(main):002:0> User.new.disabled?
=> false
irb(main):003:0> User.new.banned?
=> false
irb(main):004:0> User.new.inactive?
=> true

You can also use define_method in a similar way, which I will go over in my next post.