Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Version bump, Rails 3.2 compat (fixes #49)

  • Loading branch information...
commit e20c4dfc247f574143882b2503a633debc20eafc 1 parent e10ae63
@ernie ernie authored
View
4 Gemfile
@@ -11,10 +11,8 @@ when /\// # A path
{:path => arel}
when /^v/ # A tagged version
{:git => 'git://github.com/rails/arel.git', :tag => arel}
-when /^\w-$/ # A branch name
- {:git => 'git://github.com/rails/arel.git', :branch => arel}
else
- arel
+ {:git => 'git://github.com/rails/arel.git', :branch => arel}
end
gem 'arel', arel_opts
View
2  lib/ransack/adapters/active_record.rb
@@ -4,6 +4,8 @@
case ActiveRecord::VERSION::STRING
when /^3\.0\./
require 'ransack/adapters/active_record/3.0/context'
+when /^3\.1\./
+ require 'ransack/adapters/active_record/3.1/context'
else
require 'ransack/adapters/active_record/context'
end
View
5 lib/ransack/adapters/active_record/3.0/context.rb
@@ -10,6 +10,11 @@ class Context < ::Ransack::Context
# Because the AR::Associations namespace is insane
JoinDependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency
JoinBase = JoinDependency::JoinBase
+
+ def initialize(object, options = {})
+ super
+ @arel_visitor = Arel::Visitors.visitor_for @engine
+ end
def evaluate(search, opts = {})
viz = Visitor.new
View
163 lib/ransack/adapters/active_record/3.1/context.rb
@@ -0,0 +1,163 @@
+require 'ransack/context'
+require 'polyamorous'
+
+module Ransack
+ module Adapters
+ module ActiveRecord
+ class Context < ::Ransack::Context
+ # Because the AR::Associations namespace is insane
+ JoinDependency = ::ActiveRecord::Associations::JoinDependency
+ JoinPart = JoinDependency::JoinPart
+
+ def initialize(object, options = {})
+ super
+ @arel_visitor = Arel::Visitors.visitor_for @engine
+ end
+
+ def evaluate(search, opts = {})
+ viz = Visitor.new
+ relation = @object.except(:order).where(viz.accept(search.base)).order(viz.accept(search.sorts))
+ opts[:distinct] ? relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
+ end
+
+ def attribute_method?(str, klass = @klass)
+ exists = false
+
+ if ransackable_attribute?(str, klass)
+ exists = true
+ elsif (segments = str.split(/_/)).size > 1
+ remainder = []
+ found_assoc = nil
+ while !found_assoc && remainder.unshift(segments.pop) && segments.size > 0 do
+ assoc, poly_class = unpolymorphize_association(segments.join('_'))
+ if found_assoc = get_association(assoc, klass)
+ exists = attribute_method?(remainder.join('_'), poly_class || found_assoc.klass)
+ end
+ end
+ end
+
+ exists
+ end
+
+ def table_for(parent)
+ parent.table
+ end
+
+ def klassify(obj)
+ if Class === obj && ::ActiveRecord::Base > obj
+ obj
+ elsif obj.respond_to? :klass
+ obj.klass
+ elsif obj.respond_to? :active_record
+ obj.active_record
+ else
+ raise ArgumentError, "Don't know how to klassify #{obj}"
+ end
+ end
+
+ def type_for(attr)
+ return nil unless attr && attr.valid?
+ name = attr.arel_attribute.name.to_s
+ table = attr.arel_attribute.relation.table_name
+
+ unless @engine.connection_pool.table_exists?(table)
+ raise "No table named #{table} exists"
+ end
+
+ @engine.connection_pool.columns_hash[table][name].type
+ end
+
+ private
+
+ def get_parent_and_attribute_name(str, parent = @base)
+ attr_name = nil
+
+ if ransackable_attribute?(str, klassify(parent))
+ attr_name = str
+ elsif (segments = str.split(/_/)).size > 1
+ remainder = []
+ found_assoc = nil
+ while remainder.unshift(segments.pop) && segments.size > 0 && !found_assoc do
+ assoc, klass = unpolymorphize_association(segments.join('_'))
+ if found_assoc = get_association(assoc, parent)
+ join = build_or_find_association(found_assoc.name, parent, klass)
+ parent, attr_name = get_parent_and_attribute_name(remainder.join('_'), join)
+ end
+ end
+ end
+
+ [parent, attr_name]
+ end
+
+ def get_association(str, parent = @base)
+ klass = klassify parent
+ ransackable_association?(str, klass) &&
+ klass.reflect_on_all_associations.detect {|a| a.name.to_s == str}
+ end
+
+ def join_dependency(relation)
+ if relation.respond_to?(:join_dependency) # Squeel will enable this
+ relation.join_dependency
+ else
+ build_join_dependency(relation)
+ end
+ end
+
+ def build_join_dependency(relation)
+ buckets = relation.joins_values.group_by do |join|
+ case join
+ when String
+ 'string_join'
+ when Hash, Symbol, Array
+ 'association_join'
+ when ::ActiveRecord::Associations::JoinDependency::JoinAssociation
+ 'stashed_join'
+ when Arel::Nodes::Join
+ 'join_node'
+ else
+ raise 'unknown class: %s' % join.class.name
+ end
+ end
+
+ association_joins = buckets['association_join'] || []
+ stashed_association_joins = buckets['stashed_join'] || []
+ join_nodes = buckets['join_node'] || []
+ string_joins = (buckets['string_join'] || []).map { |x|
+ x.strip
+ }.uniq
+
+ join_list = relation.send :custom_join_ast, relation.table.from(relation.table), string_joins
+
+ join_dependency = JoinDependency.new(
+ relation.klass,
+ association_joins,
+ join_list
+ )
+
+ join_nodes.each do |join|
+ join_dependency.table_aliases[join.left.name.downcase] = 1
+ end
+
+ join_dependency.graft(*stashed_association_joins)
+ end
+
+ def build_or_find_association(name, parent = @base, klass = nil)
+ found_association = @join_dependency.join_associations.detect do |assoc|
+ assoc.reflection.name == name &&
+ assoc.parent == parent &&
+ (!klass || assoc.reflection.klass == klass)
+ end
+ unless found_association
+ @join_dependency.send(:build, Polyamorous::Join.new(name, @join_type, klass), parent)
+ found_association = @join_dependency.join_associations.last
+ # Leverage the stashed association functionality in AR
+ @object = @object.joins(found_association)
+ end
+
+ found_association
+ end
+
+ end
+ end
+ end
+end
View
150 lib/ransack/adapters/active_record/context.rb
@@ -1,157 +1,31 @@
require 'ransack/context'
+require 'ransack/adapters/active_record/3.1/context'
require 'polyamorous'
module Ransack
module Adapters
module ActiveRecord
class Context < ::Ransack::Context
- # Because the AR::Associations namespace is insane
- JoinDependency = ::ActiveRecord::Associations::JoinDependency
- JoinPart = JoinDependency::JoinPart
-
- def evaluate(search, opts = {})
- viz = Visitor.new
- relation = @object.except(:order).where(viz.accept(search.base)).order(viz.accept(search.sorts))
- opts[:distinct] ? relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
- end
-
- def attribute_method?(str, klass = @klass)
- exists = false
-
- if ransackable_attribute?(str, klass)
- exists = true
- elsif (segments = str.split(/_/)).size > 1
- remainder = []
- found_assoc = nil
- while !found_assoc && remainder.unshift(segments.pop) && segments.size > 0 do
- assoc, poly_class = unpolymorphize_association(segments.join('_'))
- if found_assoc = get_association(assoc, klass)
- exists = attribute_method?(remainder.join('_'), poly_class || found_assoc.klass)
- end
- end
- end
-
- exists
- end
-
- def table_for(parent)
- parent.table
- end
-
- def klassify(obj)
- if Class === obj && ::ActiveRecord::Base > obj
- obj
- elsif obj.respond_to? :klass
- obj.klass
- elsif obj.respond_to? :active_record
- obj.active_record
- else
- raise ArgumentError, "Don't know how to klassify #{obj}"
- end
- end
-
+
+ # Redefine a few things that have changed with 3.2.
+
+ def initialize(object, options = {})
+ super
+ @arel_visitor = @engine.connection.visitor
+ end
+
def type_for(attr)
return nil unless attr && attr.valid?
name = attr.arel_attribute.name.to_s
table = attr.arel_attribute.relation.table_name
- unless @engine.connection_pool.table_exists?(table)
+ unless @engine.connection.table_exists?(table)
raise "No table named #{table} exists"
end
- @engine.connection_pool.columns_hash[table][name].type
- end
-
- private
-
- def get_parent_and_attribute_name(str, parent = @base)
- attr_name = nil
-
- if ransackable_attribute?(str, klassify(parent))
- attr_name = str
- elsif (segments = str.split(/_/)).size > 1
- remainder = []
- found_assoc = nil
- while remainder.unshift(segments.pop) && segments.size > 0 && !found_assoc do
- assoc, klass = unpolymorphize_association(segments.join('_'))
- if found_assoc = get_association(assoc, parent)
- join = build_or_find_association(found_assoc.name, parent, klass)
- parent, attr_name = get_parent_and_attribute_name(remainder.join('_'), join)
- end
- end
- end
-
- [parent, attr_name]
+ @engine.connection.schema_cache.columns_hash[table][name].type
end
-
- def get_association(str, parent = @base)
- klass = klassify parent
- ransackable_association?(str, klass) &&
- klass.reflect_on_all_associations.detect {|a| a.name.to_s == str}
- end
-
- def join_dependency(relation)
- if relation.respond_to?(:join_dependency) # Squeel will enable this
- relation.join_dependency
- else
- build_join_dependency(relation)
- end
- end
-
- def build_join_dependency(relation)
- buckets = relation.joins_values.group_by do |join|
- case join
- when String
- 'string_join'
- when Hash, Symbol, Array
- 'association_join'
- when ::ActiveRecord::Associations::JoinDependency::JoinAssociation
- 'stashed_join'
- when Arel::Nodes::Join
- 'join_node'
- else
- raise 'unknown class: %s' % join.class.name
- end
- end
-
- association_joins = buckets['association_join'] || []
- stashed_association_joins = buckets['stashed_join'] || []
- join_nodes = buckets['join_node'] || []
- string_joins = (buckets['string_join'] || []).map { |x|
- x.strip
- }.uniq
-
- join_list = relation.send :custom_join_ast, relation.table.from(relation.table), string_joins
-
- join_dependency = JoinDependency.new(
- relation.klass,
- association_joins,
- join_list
- )
-
- join_nodes.each do |join|
- join_dependency.table_aliases[join.left.name.downcase] = 1
- end
-
- join_dependency.graft(*stashed_association_joins)
- end
-
- def build_or_find_association(name, parent = @base, klass = nil)
- found_association = @join_dependency.join_associations.detect do |assoc|
- assoc.reflection.name == name &&
- assoc.parent == parent &&
- (!klass || assoc.reflection.klass == klass)
- end
- unless found_association
- @join_dependency.send(:build, Polyamorous::Join.new(name, @join_type, klass), parent)
- found_association = @join_dependency.join_associations.last
- # Leverage the stashed association functionality in AR
- @object = @object.joins(found_association)
- end
-
- found_association
- end
-
+
end
end
end
View
1  lib/ransack/context.rb
@@ -34,7 +34,6 @@ def initialize(object, options = {})
@join_type = options[:join_type] || Arel::OuterJoin
@base = @join_dependency.join_base
@engine = @base.arel_engine
- @arel_visitor = Arel::Visitors.visitor_for @engine
@default_table = Arel::Table.new(@base.table_name, :as => @base.aliased_table_name, :engine => @engine)
@bind_pairs = Hash.new do |hash, key|
parent, attr_name = get_parent_and_attribute_name(key.to_s)
View
2  lib/ransack/version.rb
@@ -1,3 +1,3 @@
module Ransack
- VERSION = "0.5.8"
+ VERSION = "0.6.0"
end
View
8 spec/spec_helper.rb
@@ -20,7 +20,13 @@
end
RSpec.configure do |config|
- config.before(:suite) { Schema.create }
+ config.before(:suite) do
+ puts '=' * 80
+ puts "Running specs against ActiveRecord #{ActiveRecord::VERSION::STRING} and ARel #{Arel::VERSION}..."
+ puts '=' * 80
+ Schema.create
+ end
+
config.before(:all) { Sham.reset(:before_all) }
config.before(:each) { Sham.reset(:before_each) }
Please sign in to comment.
Something went wrong with that request. Please try again.