Skip to content
This repository
Browse code

fixes #1

  • Loading branch information...
commit e520edf9cf471c0304a352f67c8c8469f5e15390 1 parent 29cfd85
Larry Kyrala authored June 14, 2012
3  .gitignore
@@ -3,4 +3,5 @@
3 3
 Gemfile.lock
4 4
 doc
5 5
 coverage
6  
-pkg
  6
+pkg
  7
+.rvmrc
2  Gemfile
@@ -4,7 +4,7 @@
4 4
 source :rubygems
5 5
 
6 6
 group :test do
7  
-  #gem 'ruby-debug19'
  7
+  #gem 'debugger'
8 8
 	gem 'simplecov', :require => false
9 9
 	gem 'mocha'
10 10
 	gem 'actionpack', '2.3.11'
4  Rakefile
@@ -3,7 +3,7 @@ require 'rake/testtask'
3 3
 require 'yard'
4 4
 
5 5
 
6  
-PKG_VERSION = '0.0.6'
  6
+PKG_VERSION = '0.0.7'
7 7
 
8 8
 SRC_FILES = Dir.glob('lib/**/*')
9 9
 TST_FILES = Dir.glob('test/**/*')
@@ -25,7 +25,7 @@ spec = Gem::Specification.new do |s|
25 25
   s.description = "Conditional UI predicates for Rails - a clean and simple approach to separate business logic from your views and models."
26 26
 
27 27
   s.name        = 'condi'
28  
-  s.date        = '2011-12-14'
  28
+  s.date        = '2012-06-14'
29 29
   s.summary     = "Condi"
30 30
   s.authors     = ["Larry Kyrala"]
31 31
   s.email       = 'larry.kyrala@gmail.com'
16  lib/condi.rb
@@ -30,10 +30,24 @@ module Condi
30 30
   # @param [Proc] block {} or do...end block.
31 31
   # @note A *synonym* is an alias for defining methods that return values other than true or false.
32 32
   # @note You are not required to end a predicate with a question mark, however it is conventional in Ruby to do so.
  33
+  # @note Predicates can only be called during the request context 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).
33 34
   # @see the full example in the <a href="index.html">README</a>. 
34 35
   def predicate(method_name, &block)
35 36
     self.class.instance_eval do
36  
-      define_method(method_name, &block)
  37
+      # this is the request id at the moment the predicate is defined
  38
+      request_id = eval("request.object_id",block.binding)
  39
+
  40
+      define_method(method_name) do |*args|
  41
+        # this is the request id at the moment the predicate is called
  42
+        check_request_id = request.object_id
  43
+
  44
+        # if they don't match, raise an error!
  45
+        unless check_request_id == request_id
  46
+          #debugger
  47
+          raise RuntimeError, "predicate '#{method_name}' cannot be called outside of the request it was defined in (#{request_id}). please redefine the predicate in this request (#{check_request_id}).", caller(2)
  48
+        end
  49
+        block.call(*args)
  50
+      end
37 51
       helper_method(method_name)
38 52
     end
39 53
   end
20  test/test_condi.rb
@@ -9,7 +9,7 @@
9 9
 
10 10
 require 'ostruct'
11 11
 
12  
-#require 'ruby-debug'
  12
+#require 'debugger'
13 13
 
14 14
 
15 15
 class CondiTest < Test::Unit::TestCase
@@ -142,4 +142,22 @@ def test_synonyms
142 142
   end
143 143
   
144 144
 
  145
+  # fix for https://github.com/coldnebo/condi/issues/1
  146
+  def test_lifespan
  147
+    @controller_instance.request = Object.new   # simulate the first request
  148
+    @controller_instance.instance_eval do 
  149
+      predicate(:always_be_true?) { true }
  150
+    end
  151
+
  152
+    assert @controller_instance.respond_to?(:always_be_true?)
  153
+    assert @controller_instance.always_be_true? == true
  154
+
  155
+    @controller_instance.request = Object.new   # simulate a second request
  156
+
  157
+    # now, if a view calls the predicate, we shouldn't allow it!
  158
+    assert_raise RuntimeError do
  159
+      @controller_instance.always_be_true? 
  160
+    end
  161
+  end
  162
+
145 163
 end

0 notes on commit e520edf

Please sign in to comment.
Something went wrong with that request. Please try again.