Skip to content

Commit

Permalink
Merge pull request #407 from Zhomart/mongoid
Browse files Browse the repository at this point in the history
Mongoid 4.0 support
  • Loading branch information
jonatack committed Nov 3, 2014
2 parents c3a93d6 + e90ffd1 commit 438fe2f
Show file tree
Hide file tree
Showing 44 changed files with 2,418 additions and 211 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
services: mongodb

language: ruby

sudo: false
Expand All @@ -8,9 +10,11 @@ rvm:
- 1.9

env:
- RAILS=master DB=mongodb
- RAILS=master DB=sqlite3
- RAILS=master DB=mysql
- RAILS=master DB=postgres
- RAILS=4-1-stable DB=mongodb
- RAILS=4-1-stable DB=sqlite3
- RAILS=4-1-stable DB=mysql
- RAILS=4-1-stable DB=postgres
Expand Down
12 changes: 9 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,35 @@ end

gem 'polyamorous', '~> 1.1'

gem 'pry'

# Provide timezone information on Windows
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]

case rails
when /\// # A path
gem 'activesupport', path: "#{rails}/activesupport"
gem 'activerecord', path: "#{rails}/activerecord"
gem 'activerecord', path: "#{rails}/activerecord", require: false
gem 'actionpack', path: "#{rails}/actionpack"
when /^v/ # A tagged version
git 'git://github.com/rails/rails.git', :tag => rails do
gem 'activesupport'
gem 'activemodel'
gem 'activerecord'
gem 'activerecord', require: false
gem 'actionpack'
end
else
git 'git://github.com/rails/rails.git', :branch => rails do
gem 'activesupport'
gem 'activemodel'
gem 'activerecord'
gem 'activerecord', require: false
gem 'actionpack'
end
if rails == '3-0-stable'
gem 'mysql2', '< 0.3'
end
end

if ENV['DB'] =~ /mongodb/
gem 'mongoid', '~> 4.0.0', require: false
end
28 changes: 26 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,22 @@ require 'rspec/core/rake_task'
Bundler::GemHelper.install_tasks

RSpec::Core::RakeTask.new(:spec) do |rspec|
ENV['SPEC'] = 'spec/ransack/**/*_spec.rb'
rspec.rspec_opts = ['--backtrace']
end

task :default => :spec
RSpec::Core::RakeTask.new(:mongoid) do |rspec|
ENV['SPEC'] = 'spec/mongoid/**/*_spec.rb'
rspec.rspec_opts = ['--backtrace']
end

task :default do
if ENV['DB'] =~ /mongodb/
Rake::Task["mongoid"].invoke
else
Rake::Task["spec"].invoke
end
end

desc "Open an irb session with Ransack and the sample data used in specs"
task :console do
Expand All @@ -16,4 +28,16 @@ task :console do
require 'console'
ARGV.clear
IRB.start
end
end

desc "Open an irb session with Ransack, Mongoid and the sample data used in specs"
task :mongoid_console do
require 'irb'
require 'irb/completion'
require 'pry'
require 'mongoid'
require File.expand_path('../lib/ransack.rb', __FILE__)
require File.expand_path('../spec/mongoid/support/schema.rb', __FILE__)
ARGV.clear
Pry.start
end
9 changes: 9 additions & 0 deletions lib/ransack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

require 'ransack/configuration'

if defined?(::Mongoid)
require 'ransack/adapters/mongoid/ransack/constants'
else
require 'ransack/adapters/active_record/ransack/constants'
end

module Ransack
extend Configuration

Expand All @@ -19,9 +25,12 @@ class UntraversableAssociationError < StandardError; end;
end

require 'ransack/translate'
require 'ransack/adapters/active_record/ransack/translate' if defined?(::ActiveRecord::Base)
require 'ransack/adapters/mongoid/ransack/translate' if defined?(::Mongoid)
require 'ransack/search'
require 'ransack/ransacker'
require 'ransack/adapters/active_record' if defined?(::ActiveRecord::Base)
require 'ransack/adapters/mongoid' if defined?(::Mongoid)
require 'ransack/helpers'
require 'action_controller'

Expand Down
127 changes: 127 additions & 0 deletions lib/ransack/adapters/active_record/ransack/constants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
module Ransack
module Constants
DISTINCT = 'DISTINCT '.freeze
STRING_JOIN = 'string_join'.freeze
ASSOCIATION_JOIN = 'association_join'.freeze
STASHED_JOIN = 'stashed_join'.freeze
JOIN_NODE = 'join_node'.freeze

DERIVED_PREDICATES = [
['cont'.freeze, {
:arel_predicate => 'matches'.freeze,
:formatter => proc { |v| "%#{escape_wildcards(v)}%" }
}
],
['i_cont'.freeze, {
:arel_predicate => 'i_matches'.freeze,
:formatter => proc { |v| "%#{escape_wildcards(v)}%" }
}
],
['not_cont'.freeze, {
:arel_predicate => 'does_not_match'.freeze,
:formatter => proc { |v| "%#{escape_wildcards(v)}%" }
}
],
['i_not_cont'.freeze, {
:arel_predicate => 'i_does_not_match'.freeze,
:formatter => proc { |v| "%#{escape_wildcards(v)}%" }
}
],
['start'.freeze, {
:arel_predicate => 'matches'.freeze,
:formatter => proc { |v| "#{escape_wildcards(v)}%" }
}
],
['not_start'.freeze, {
:arel_predicate => 'does_not_match'.freeze,
:formatter => proc { |v| "#{escape_wildcards(v)}%" }
}
],
['end'.freeze, {
:arel_predicate => 'matches'.freeze,
:formatter => proc { |v| "%#{escape_wildcards(v)}" }
}
],
['not_end'.freeze, {
:arel_predicate => 'does_not_match'.freeze,
:formatter => proc { |v| "%#{escape_wildcards(v)}" }
}
],
['true'.freeze, {
:arel_predicate => proc { |v| v ? EQ : NOT_EQ },
:compounds => false,
:type => :boolean,
:validator => proc { |v| BOOLEAN_VALUES.include?(v) },
:formatter => proc { |v| true }
}
],
['not_true'.freeze, {
:arel_predicate => proc { |v| v ? NOT_EQ : EQ },
:compounds => false,
:type => :boolean,
:validator => proc { |v| BOOLEAN_VALUES.include?(v) },
:formatter => proc { |v| true }
}
],
['false'.freeze, {
:arel_predicate => proc { |v| v ? EQ : NOT_EQ },
:compounds => false,
:type => :boolean,
:validator => proc { |v| BOOLEAN_VALUES.include?(v) },
:formatter => proc { |v| false }
}
],
['not_false'.freeze, {
:arel_predicate => proc { |v| v ? NOT_EQ : EQ },
:compounds => false,
:type => :boolean,
:validator => proc { |v| BOOLEAN_VALUES.include?(v) },
:formatter => proc { |v| false }
}
],
['present'.freeze, {
:arel_predicate => proc { |v| v ? NOT_EQ_ALL : EQ_ANY },
:compounds => false,
:type => :boolean,
:validator => proc { |v| BOOLEAN_VALUES.include?(v) },
:formatter => proc { |v| [nil, Ransack::Constants::EMPTY] }
}
],
['blank'.freeze, {
:arel_predicate => proc { |v| v ? EQ_ANY : NOT_EQ_ALL },
:compounds => false,
:type => :boolean,
:validator => proc { |v| BOOLEAN_VALUES.include?(v) },
:formatter => proc { |v| [nil, Ransack::Constants::EMPTY] }
}
],
['null'.freeze, {
:arel_predicate => proc { |v| v ? EQ : NOT_EQ },
:compounds => false,
:type => :boolean,
:validator => proc { |v| BOOLEAN_VALUES.include?(v)},
:formatter => proc { |v| nil }
}
],
['not_null'.freeze, {
:arel_predicate => proc { |v| v ? NOT_EQ : EQ },
:compounds => false,
:type => :boolean,
:validator => proc { |v| BOOLEAN_VALUES.include?(v) },
:formatter => proc { |v| nil } }
]
].freeze

module_function
# replace % \ to \% \\
def escape_wildcards(unescaped)
case ActiveRecord::Base.connection.adapter_name
when "Mysql2".freeze, "PostgreSQL".freeze
# Necessary for PostgreSQL and MySQL
unescaped.to_s.gsub(/([\\|\%|.])/, '\\\\\\1')
else
unescaped
end
end
end
end
64 changes: 64 additions & 0 deletions lib/ransack/adapters/active_record/ransack/context.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require 'ransack/visitor'

module Ransack
class Context
attr_reader :arel_visitor

class << self

def for_class(klass, options = {})
if klass < ActiveRecord::Base
Adapters::ActiveRecord::Context.new(klass, options)
end
end

def for_object(object, options = {})
case object
when ActiveRecord::Relation
Adapters::ActiveRecord::Context.new(object.klass, options)
end
end

end # << self

def initialize(object, options = {})
@object = relation_for(object)
@klass = @object.klass
@join_dependency = join_dependency(@object)
@join_type = options[:join_type] || Polyamorous::OuterJoin
@search_key = options[:search_key] || Ransack.options[:search_key]

if ::ActiveRecord::VERSION::STRING >= "4.1".freeze
@base = @join_dependency.join_root
@engine = @base.base_klass.arel_engine
else
@base = @join_dependency.join_base
@engine = @base.arel_engine
end

@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)
if parent && attr_name
hash[key] = [parent, attr_name]
end
end
end

def klassify(obj)
if Class === obj && ::ActiveRecord::Base > obj
obj
elsif obj.respond_to? :klass
obj.klass
elsif obj.respond_to? :active_record # Rails 3
obj.active_record
elsif obj.respond_to? :base_klass # Rails 4
obj.base_klass
else
raise ArgumentError, "Don't know how to klassify #{obj.inspect}"
end
end
end
end
27 changes: 27 additions & 0 deletions lib/ransack/adapters/active_record/ransack/nodes/condition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Ransack
module Nodes
class Condition

def arel_predicate
predicates = attributes.map do |attr|
attr.attr.send(
arel_predicate_for_attribute(attr),
formatted_values_for_attribute(attr)
)
end

if predicates.size > 1
case combinator
when Ransack::Constants::AND
Arel::Nodes::Grouping.new(Arel::Nodes::And.new(predicates))
when Ransack::Constants::OR
predicates.inject(&:or)
end
else
predicates.first
end
end

end # Condition
end
end
12 changes: 12 additions & 0 deletions lib/ransack/adapters/active_record/ransack/translate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Ransack
module Translate

def self.i18n_key(klass)
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0
klass.model_name.i18n_key.to_s.tr('.'.freeze, '/'.freeze)
else
klass.model_name.i18n_key.to_s
end
end
end
end
24 changes: 24 additions & 0 deletions lib/ransack/adapters/active_record/ransack/visitor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Ransack
class Visitor
def visit_and(object)
nodes = object.values.map { |o| accept(o) }.compact
return nil unless nodes.size > 0

if nodes.size > 1
Arel::Nodes::Grouping.new(Arel::Nodes::And.new(nodes))
else
nodes.first
end
end

def quoted?(object)
case object
when Arel::Nodes::SqlLiteral, Bignum, Fixnum
false
else
true
end
end

end
end
13 changes: 13 additions & 0 deletions lib/ransack/adapters/mongoid.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'ransack/adapters/mongoid/base'
::Mongoid::Document.send :include, Ransack::Adapters::Mongoid::Base

require 'ransack/adapters/mongoid/attributes/attribute'
require 'ransack/adapters/mongoid/table'
require 'ransack/adapters/mongoid/inquiry_hash'

case ::Mongoid::VERSION
when /^3\.2\./
require 'ransack/adapters/mongoid/3.2/context'
else
require 'ransack/adapters/mongoid/context'
end
Empty file.
Loading

0 comments on commit 438fe2f

Please sign in to comment.