Module: Rollable::Base

Defined in:
lib/rollable/base.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

TODO: Don’t need method_missing no more, use dynamic dispatch instead.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/rollable/base.rb', line 114

def method_missing(method, *args)
  if !(method =~ /is_a\?/) && method =~ /^is_([a-z]+)(?:_(?:on|of))?\?$/ #Common spell to match against regex
    role = $1
    that_thing = args.first.presence
    object = that_thing.class.to_s if that_thing
    self.class_eval do #Open my class definition
      if that_thing
        define_method(method) do |thing| # Define the method. Helps a lot in performance
          self.roles.where("rollable_type = ? AND name = ?", object, role).inject(false) do |v,o| # You can't do an inner join on polymorphic relationships, unfortunately.
            v ||= (o.rollable == thing)
          end
        end
      else
        define_method(method) do
          self.roles.where("name = ?", role).count > 0
        end
      end
    end
    if that_thing
      self.public_send(method, that_thing) # And of course, call the method.
    else
      self.public_send(method)
    end
  else
    super
  end
end

Class Method Details

.included(base) ⇒ Object



5
6
7
8
# File 'lib/rollable/base.rb', line 5

def self.included(base)
  base.extend(ClassMethods)
  base.send(:has_many, :roles)
end

Instance Method Details

#respond_to?(method, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


142
143
144
145
146
147
148
# File 'lib/rollable/base.rb', line 142

def respond_to?(method, include_private=false)
  if !(method =~ /is_a\?/) && method =~ /^is_([a-z]+)(?:_(?:on|of))?\?$/
    self.class.role_names.include?($1)
  else
    super
  end
end