Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Version bump, Rails 3.2 compat (fixes #49)

  • Loading branch information...
commit e20c4dfc247f574143882b2503a633debc20eafc 1 parent e10ae63
Ernie Miller authored January 20, 2012
4  Gemfile
@@ -11,10 +11,8 @@ when /\// # A path
11 11
   {:path => arel}
12 12
 when /^v/ # A tagged version
13 13
   {:git => 'git://github.com/rails/arel.git', :tag => arel}
14  
-when /^\w-$/ # A branch name
15  
-  {:git => 'git://github.com/rails/arel.git', :branch => arel}
16 14
 else
17  
-  arel
  15
+  {:git => 'git://github.com/rails/arel.git', :branch => arel}
18 16
 end
19 17
 
20 18
 gem 'arel', arel_opts
2  lib/ransack/adapters/active_record.rb
@@ -4,6 +4,8 @@
4 4
 case ActiveRecord::VERSION::STRING
5 5
 when /^3\.0\./
6 6
   require 'ransack/adapters/active_record/3.0/context'
  7
+when /^3\.1\./
  8
+  require 'ransack/adapters/active_record/3.1/context'
7 9
 else
8 10
   require 'ransack/adapters/active_record/context'
9 11
 end
5  lib/ransack/adapters/active_record/3.0/context.rb
@@ -10,6 +10,11 @@ class Context < ::Ransack::Context
10 10
         # Because the AR::Associations namespace is insane
11 11
         JoinDependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency
12 12
         JoinBase = JoinDependency::JoinBase
  13
+        
  14
+        def initialize(object, options = {})
  15
+          super
  16
+          @arel_visitor = Arel::Visitors.visitor_for @engine
  17
+        end
13 18
 
14 19
         def evaluate(search, opts = {})
15 20
           viz = Visitor.new
163  lib/ransack/adapters/active_record/3.1/context.rb
... ...
@@ -0,0 +1,163 @@
  1
+require 'ransack/context'
  2
+require 'polyamorous'
  3
+
  4
+module Ransack
  5
+  module Adapters
  6
+    module ActiveRecord
  7
+      class Context < ::Ransack::Context
  8
+        # Because the AR::Associations namespace is insane
  9
+        JoinDependency = ::ActiveRecord::Associations::JoinDependency
  10
+        JoinPart = JoinDependency::JoinPart
  11
+        
  12
+        def initialize(object, options = {})
  13
+          super
  14
+          @arel_visitor = Arel::Visitors.visitor_for @engine
  15
+        end
  16
+
  17
+        def evaluate(search, opts = {})
  18
+          viz = Visitor.new
  19
+          relation = @object.except(:order).where(viz.accept(search.base)).order(viz.accept(search.sorts))
  20
+          opts[:distinct] ? relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
  21
+        end
  22
+
  23
+        def attribute_method?(str, klass = @klass)
  24
+          exists = false
  25
+
  26
+          if ransackable_attribute?(str, klass)
  27
+            exists = true
  28
+          elsif (segments = str.split(/_/)).size > 1
  29
+            remainder = []
  30
+            found_assoc = nil
  31
+            while !found_assoc && remainder.unshift(segments.pop) && segments.size > 0 do
  32
+              assoc, poly_class = unpolymorphize_association(segments.join('_'))
  33
+              if found_assoc = get_association(assoc, klass)
  34
+                exists = attribute_method?(remainder.join('_'), poly_class || found_assoc.klass)
  35
+              end
  36
+            end
  37
+          end
  38
+
  39
+          exists
  40
+        end
  41
+
  42
+        def table_for(parent)
  43
+          parent.table
  44
+        end
  45
+
  46
+        def klassify(obj)
  47
+          if Class === obj && ::ActiveRecord::Base > obj
  48
+            obj
  49
+          elsif obj.respond_to? :klass
  50
+            obj.klass
  51
+          elsif obj.respond_to? :active_record
  52
+            obj.active_record
  53
+          else
  54
+            raise ArgumentError, "Don't know how to klassify #{obj}"
  55
+          end
  56
+        end
  57
+
  58
+        def type_for(attr)
  59
+          return nil unless attr && attr.valid?
  60
+          name    = attr.arel_attribute.name.to_s
  61
+          table   = attr.arel_attribute.relation.table_name
  62
+
  63
+          unless @engine.connection_pool.table_exists?(table)
  64
+            raise "No table named #{table} exists"
  65
+          end
  66
+
  67
+          @engine.connection_pool.columns_hash[table][name].type
  68
+        end
  69
+
  70
+        private
  71
+
  72
+        def get_parent_and_attribute_name(str, parent = @base)
  73
+          attr_name = nil
  74
+
  75
+          if ransackable_attribute?(str, klassify(parent))
  76
+            attr_name = str
  77
+          elsif (segments = str.split(/_/)).size > 1
  78
+            remainder = []
  79
+            found_assoc = nil
  80
+            while remainder.unshift(segments.pop) && segments.size > 0 && !found_assoc do
  81
+              assoc, klass = unpolymorphize_association(segments.join('_'))
  82
+              if found_assoc = get_association(assoc, parent)
  83
+                join = build_or_find_association(found_assoc.name, parent, klass)
  84
+                parent, attr_name = get_parent_and_attribute_name(remainder.join('_'), join)
  85
+              end
  86
+            end
  87
+          end
  88
+
  89
+          [parent, attr_name]
  90
+        end
  91
+
  92
+        def get_association(str, parent = @base)
  93
+          klass = klassify parent
  94
+          ransackable_association?(str, klass) &&
  95
+          klass.reflect_on_all_associations.detect {|a| a.name.to_s == str}
  96
+        end
  97
+
  98
+        def join_dependency(relation)
  99
+          if relation.respond_to?(:join_dependency) # Squeel will enable this
  100
+            relation.join_dependency
  101
+          else
  102
+            build_join_dependency(relation)
  103
+          end
  104
+        end
  105
+
  106
+        def build_join_dependency(relation)
  107
+          buckets = relation.joins_values.group_by do |join|
  108
+            case join
  109
+            when String
  110
+              'string_join'
  111
+            when Hash, Symbol, Array
  112
+              'association_join'
  113
+            when ::ActiveRecord::Associations::JoinDependency::JoinAssociation
  114
+              'stashed_join'
  115
+            when Arel::Nodes::Join
  116
+              'join_node'
  117
+            else
  118
+              raise 'unknown class: %s' % join.class.name
  119
+            end
  120
+          end
  121
+
  122
+          association_joins         = buckets['association_join'] || []
  123
+          stashed_association_joins = buckets['stashed_join'] || []
  124
+          join_nodes                = buckets['join_node'] || []
  125
+          string_joins              = (buckets['string_join'] || []).map { |x|
  126
+            x.strip
  127
+          }.uniq
  128
+
  129
+          join_list = relation.send :custom_join_ast, relation.table.from(relation.table), string_joins
  130
+
  131
+          join_dependency = JoinDependency.new(
  132
+            relation.klass,
  133
+            association_joins,
  134
+            join_list
  135
+          )
  136
+
  137
+          join_nodes.each do |join|
  138
+            join_dependency.table_aliases[join.left.name.downcase] = 1
  139
+          end
  140
+
  141
+          join_dependency.graft(*stashed_association_joins)
  142
+        end
  143
+
  144
+        def build_or_find_association(name, parent = @base, klass = nil)
  145
+          found_association = @join_dependency.join_associations.detect do |assoc|
  146
+            assoc.reflection.name == name &&
  147
+            assoc.parent == parent &&
  148
+            (!klass || assoc.reflection.klass == klass)
  149
+          end
  150
+          unless found_association
  151
+            @join_dependency.send(:build, Polyamorous::Join.new(name, @join_type, klass), parent)
  152
+            found_association = @join_dependency.join_associations.last
  153
+            # Leverage the stashed association functionality in AR
  154
+            @object = @object.joins(found_association)
  155
+          end
  156
+
  157
+          found_association
  158
+        end
  159
+
  160
+      end
  161
+    end
  162
+  end
  163
+end
150  lib/ransack/adapters/active_record/context.rb
... ...
@@ -1,157 +1,31 @@
1 1
 require 'ransack/context'
  2
+require 'ransack/adapters/active_record/3.1/context'
2 3
 require 'polyamorous'
3 4
 
4 5
 module Ransack
5 6
   module Adapters
6 7
     module ActiveRecord
7 8
       class Context < ::Ransack::Context
8  
-        # Because the AR::Associations namespace is insane
9  
-        JoinDependency = ::ActiveRecord::Associations::JoinDependency
10  
-        JoinPart = JoinDependency::JoinPart
11  
-
12  
-        def evaluate(search, opts = {})
13  
-          viz = Visitor.new
14  
-          relation = @object.except(:order).where(viz.accept(search.base)).order(viz.accept(search.sorts))
15  
-          opts[:distinct] ? relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
16  
-        end
17  
-
18  
-        def attribute_method?(str, klass = @klass)
19  
-          exists = false
20  
-
21  
-          if ransackable_attribute?(str, klass)
22  
-            exists = true
23  
-          elsif (segments = str.split(/_/)).size > 1
24  
-            remainder = []
25  
-            found_assoc = nil
26  
-            while !found_assoc && remainder.unshift(segments.pop) && segments.size > 0 do
27  
-              assoc, poly_class = unpolymorphize_association(segments.join('_'))
28  
-              if found_assoc = get_association(assoc, klass)
29  
-                exists = attribute_method?(remainder.join('_'), poly_class || found_assoc.klass)
30  
-              end
31  
-            end
32  
-          end
33  
-
34  
-          exists
35  
-        end
36  
-
37  
-        def table_for(parent)
38  
-          parent.table
39  
-        end
40  
-
41  
-        def klassify(obj)
42  
-          if Class === obj && ::ActiveRecord::Base > obj
43  
-            obj
44  
-          elsif obj.respond_to? :klass
45  
-            obj.klass
46  
-          elsif obj.respond_to? :active_record
47  
-            obj.active_record
48  
-          else
49  
-            raise ArgumentError, "Don't know how to klassify #{obj}"
50  
-          end
51  
-        end
52  
-
  9
+        
  10
+        # Redefine a few things that have changed with 3.2.
  11
+        
  12
+        def initialize(object, options = {})
  13
+          super
  14
+          @arel_visitor = @engine.connection.visitor
  15
+        end
  16
+        
53 17
         def type_for(attr)
54 18
           return nil unless attr && attr.valid?
55 19
           name    = attr.arel_attribute.name.to_s
56 20
           table   = attr.arel_attribute.relation.table_name
57 21
 
58  
-          unless @engine.connection_pool.table_exists?(table)
  22
+          unless @engine.connection.table_exists?(table)
59 23
             raise "No table named #{table} exists"
60 24
           end
61 25
 
62  
-          @engine.connection_pool.columns_hash[table][name].type
63  
-        end
64  
-
65  
-        private
66  
-
67  
-        def get_parent_and_attribute_name(str, parent = @base)
68  
-          attr_name = nil
69  
-
70  
-          if ransackable_attribute?(str, klassify(parent))
71  
-            attr_name = str
72  
-          elsif (segments = str.split(/_/)).size > 1
73  
-            remainder = []
74  
-            found_assoc = nil
75  
-            while remainder.unshift(segments.pop) && segments.size > 0 && !found_assoc do
76  
-              assoc, klass = unpolymorphize_association(segments.join('_'))
77  
-              if found_assoc = get_association(assoc, parent)
78  
-                join = build_or_find_association(found_assoc.name, parent, klass)
79  
-                parent, attr_name = get_parent_and_attribute_name(remainder.join('_'), join)
80  
-              end
81  
-            end
82  
-          end
83  
-
84  
-          [parent, attr_name]
  26
+          @engine.connection.schema_cache.columns_hash[table][name].type
85 27
         end
86  
-
87  
-        def get_association(str, parent = @base)
88  
-          klass = klassify parent
89  
-          ransackable_association?(str, klass) &&
90  
-          klass.reflect_on_all_associations.detect {|a| a.name.to_s == str}
91  
-        end
92  
-
93  
-        def join_dependency(relation)
94  
-          if relation.respond_to?(:join_dependency) # Squeel will enable this
95  
-            relation.join_dependency
96  
-          else
97  
-            build_join_dependency(relation)
98  
-          end
99  
-        end
100  
-
101  
-        def build_join_dependency(relation)
102  
-          buckets = relation.joins_values.group_by do |join|
103  
-            case join
104  
-            when String
105  
-              'string_join'
106  
-            when Hash, Symbol, Array
107  
-              'association_join'
108  
-            when ::ActiveRecord::Associations::JoinDependency::JoinAssociation
109  
-              'stashed_join'
110  
-            when Arel::Nodes::Join
111  
-              'join_node'
112  
-            else
113  
-              raise 'unknown class: %s' % join.class.name
114  
-            end
115  
-          end
116  
-
117  
-          association_joins         = buckets['association_join'] || []
118  
-          stashed_association_joins = buckets['stashed_join'] || []
119  
-          join_nodes                = buckets['join_node'] || []
120  
-          string_joins              = (buckets['string_join'] || []).map { |x|
121  
-            x.strip
122  
-          }.uniq
123  
-
124  
-          join_list = relation.send :custom_join_ast, relation.table.from(relation.table), string_joins
125  
-
126  
-          join_dependency = JoinDependency.new(
127  
-            relation.klass,
128  
-            association_joins,
129  
-            join_list
130  
-          )
131  
-
132  
-          join_nodes.each do |join|
133  
-            join_dependency.table_aliases[join.left.name.downcase] = 1
134  
-          end
135  
-
136  
-          join_dependency.graft(*stashed_association_joins)
137  
-        end
138  
-
139  
-        def build_or_find_association(name, parent = @base, klass = nil)
140  
-          found_association = @join_dependency.join_associations.detect do |assoc|
141  
-            assoc.reflection.name == name &&
142  
-            assoc.parent == parent &&
143  
-            (!klass || assoc.reflection.klass == klass)
144  
-          end
145  
-          unless found_association
146  
-            @join_dependency.send(:build, Polyamorous::Join.new(name, @join_type, klass), parent)
147  
-            found_association = @join_dependency.join_associations.last
148  
-            # Leverage the stashed association functionality in AR
149  
-            @object = @object.joins(found_association)
150  
-          end
151  
-
152  
-          found_association
153  
-        end
154  
-
  28
+        
155 29
       end
156 30
     end
157 31
   end
1  lib/ransack/context.rb
@@ -34,7 +34,6 @@ def initialize(object, options = {})
34 34
       @join_type = options[:join_type] || Arel::OuterJoin
35 35
       @base = @join_dependency.join_base
36 36
       @engine = @base.arel_engine
37  
-      @arel_visitor = Arel::Visitors.visitor_for @engine
38 37
       @default_table = Arel::Table.new(@base.table_name, :as => @base.aliased_table_name, :engine => @engine)
39 38
       @bind_pairs = Hash.new do |hash, key|
40 39
         parent, attr_name = get_parent_and_attribute_name(key.to_s)
2  lib/ransack/version.rb
... ...
@@ -1,3 +1,3 @@
1 1
 module Ransack
2  
-  VERSION = "0.5.8"
  2
+  VERSION = "0.6.0"
3 3
 end
8  spec/spec_helper.rb
@@ -20,7 +20,13 @@
20 20
 end
21 21
 
22 22
 RSpec.configure do |config|
23  
-  config.before(:suite) { Schema.create }
  23
+  config.before(:suite) do
  24
+    puts '=' * 80
  25
+    puts "Running specs against ActiveRecord #{ActiveRecord::VERSION::STRING} and ARel #{Arel::VERSION}..."
  26
+    puts '=' * 80
  27
+    Schema.create
  28
+  end
  29
+
24 30
   config.before(:all)   { Sham.reset(:before_all) }
25 31
   config.before(:each)  { Sham.reset(:before_each) }
26 32
 

0 notes on commit e20c4df

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