Module: Condi
- Defined in:
- lib/condi/condi.rb,
lib/version.rb,
lib/condi/version.rb
Overview
Include this module in an ActionController to define predicates or synonyms within an action context that can be used later in the related action view.
Constant Summary collapse
- VERSION =
"1.0.0"
Instance Method Summary collapse
-
#predicate(method_name, &block) ⇒ Object
(also: #synonym)
define a method on the controller which is callable from the related view and returns a true or false value.
Instance Method Details
#predicate(method_name, &block) ⇒ Object Also known as: synonym
A synonym is an alias for defining methods that return values other than true or false.
You are not required to end a predicate with a question mark, however it is conventional in Ruby to do so.
Predicates can only be called during the request scope they are defined in, otherwise a RuntimeError is raised. This restriction prevents the associated closures from inadvertently leaking previous request data when the controller classes are cached (i.e. in production).
Predicates are semantically lambdas and may contain returns.
define a method on the controller which is callable from the related view and returns a true or false value.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/condi/condi.rb', line 36 def predicate(method_name, &block) self.class.instance_eval do # this is the request id at the moment the predicate is defined request_id = eval("request.object_id",block.binding) # We need to keep the block impl as a method/lambda so that it supports returns # by using this particular invocation of define_method... method_name_impl = "impl_#{method_name}".to_sym define_method(method_name_impl, &block) # Next, this invocation of define_method creates a Proc, which # wraps the impl and allows us to check the request id. define_method(method_name) do |*args| # this is the request id at the moment the predicate is called check_request_id = request.object_id # if they don't match, raise an error! unless check_request_id == request_id raise RuntimeError, "predicate '#{method_name}' cannot be called outside of the request scope it was defined in (#{request_id}). please redefine the predicate in this request scope (#{check_request_id}).", caller(2) end send(method_name_impl, *args) end # finally, expose the wrapped predicate to the view. helper_method(method_name) end end |