Using class_eval to dynamically define predicate methods
Originally posted on agemofablog on 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 class_eval and define_method.
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?
=> trueYou can also use define_method in a similar way, which I will go over in my next post.
