diff --git a/.travis.yml b/.travis.yml index 1ff4edd..193b6e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,12 +9,21 @@ rvm: - 2.1.1 env: - - RAILS=4-0-stable DB=sqlite3 - - RAILS=4-0-stable DB=mysql - - RAILS=4-0-stable DB=postgres - RAILS=4-1-stable DB=sqlite3 - RAILS=4-1-stable DB=mysql - RAILS=4-1-stable DB=postgres + - RAILS=4-0-stable DB=sqlite3 + - RAILS=4-0-stable DB=mysql + - RAILS=4-0-stable DB=postgres + - RAILS=3-2-stable DB=sqlite + - RAILS=3-2-stable DB=mysql + - RAILS=3-2-stable DB=postgres + - RAILS=3-1-stable DB=sqlite + - RAILS=3-1-stable DB=mysql + - RAILS=3-1-stable DB=postgres + - RAILS=3-0-stable DB=sqlite + - RAILS=3-0-stable DB=mysql + - RAILS=3-0-stable DB=postgres before_script: - mysql -e 'create database ransack collate utf8_general_ci;' diff --git a/Gemfile b/Gemfile index 56f4e5a..0a46991 100644 --- a/Gemfile +++ b/Gemfile @@ -27,4 +27,7 @@ else gem 'activerecord' gem 'actionpack' end + if rails == '3-0-stable' + gem 'mysql2', '< 0.3' + end end diff --git a/README.md b/README.md index 8978582..b6be837 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,15 @@ Once you've done so, you can make use of the helpers in Ransack::Helpers::FormBu construct much more complex search forms, such as the one on the [demo page](http://ransack-demo.heroku.com) (source code [here](https://github.com/activerecord-hackery/ransack_demo)). +### Ransack #search method + +Ransack will try to to make `#search` available in your models, but in the case that `#search` has already been defined, you can use `#ransack` instead. For example the following would be equivalent: + +``` +Article.search(params[:q]) +Article.ransack(params[:q]) +``` + ### has_many and belongs_to associations You can easily use Ransack to search in associated objects. diff --git a/lib/ransack.rb b/lib/ransack.rb index f046ef7..e8d826b 100644 --- a/lib/ransack.rb +++ b/lib/ransack.rb @@ -25,4 +25,4 @@ require 'ransack/adapters/active_record' if defined?(::ActiveRecord::Base) require 'ransack/helpers' require 'action_controller' -ActionController::Base.helper Ransack::Helpers::FormHelper \ No newline at end of file +ActionController::Base.helper Ransack::Helpers::FormHelper diff --git a/lib/ransack/adapters/active_record/3.0/compat.rb b/lib/ransack/adapters/active_record/3.0/compat.rb index a040ca4..932c09a 100644 --- a/lib/ransack/adapters/active_record/3.0/compat.rb +++ b/lib/ransack/adapters/active_record/3.0/compat.rb @@ -2,7 +2,7 @@ if Arel::Nodes::And < Arel::Nodes::Binary class Ransack::Visitor def visit_Ransack_Nodes_And(object) - nodes = object.values.map {|o| accept(o)}.compact + nodes = object.values.map { |o| accept(o) }.compact return nil unless nodes.size > 0 if nodes.size > 1 @@ -132,9 +132,15 @@ module Arel end def visit_Arel_Nodes_NamedFunction o - "#{o.name}(#{o.distinct ? 'DISTINCT ' : ''}#{o.expressions.map { |x| - visit x - }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}" + "#{ + o.name + }(#{ + o.distinct ? 'DISTINCT ' : '' + }#{ + o.expressions.map { |x| visit x }.join(', ') + })#{ + o.alias ? " AS #{visit o.alias}" : '' + }" end def visit_Arel_Nodes_And o @@ -146,13 +152,17 @@ module Arel end def visit_Arel_Nodes_Values o - "VALUES (#{o.expressions.zip(o.columns).map { |value, attr| + "VALUES (#{ + o.expressions.zip(o.columns) + .map { |value, attr| if Nodes::SqlLiteral === value visit_Arel_Nodes_SqlLiteral value else quote(value, attr && column_for(attr)) end - }.join ', '})" + } + .join ', ' + })" end end end diff --git a/lib/ransack/adapters/active_record/3.0/context.rb b/lib/ransack/adapters/active_record/3.0/context.rb index b05b049..ec5f380 100644 --- a/lib/ransack/adapters/active_record/3.0/context.rb +++ b/lib/ransack/adapters/active_record/3.0/context.rb @@ -11,6 +11,8 @@ module Ransack JoinDependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency JoinBase = JoinDependency::JoinBase + # Redefine a few things for ActiveRecord 3.0. + def initialize(object, options = {}) super @arel_visitor = Arel::Visitors.visitor_for @engine @@ -24,10 +26,11 @@ module Ransack viz = Visitor.new relation = @object.where(viz.accept(search.base)) if search.sorts.any? - relation = relation.except(:order).reorder(viz.accept(search.sorts)) + relation = relation.except(:order) + .reorder(viz.accept(search.sorts)) end - opts[:distinct] ? relation.select( - "DISTINCT #{@klass.quoted_table_name}.*") : relation + opts[:distinct] ? + relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation end def attribute_method?(str, klass = @klass) @@ -38,10 +41,15 @@ module Ransack 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('_')) + 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) + exists = attribute_method?( + remainder.join('_'), poly_class || found_assoc.klass + ) end end end @@ -52,10 +60,12 @@ module Ransack def table_for(parent) parent.table end - + def type_for(attr) return nil unless attr && attr.valid? - klassify(attr.parent).columns_hash[attr.arel_attribute.name.to_s].type + klassify(attr.parent) + .columns_hash[attr.arel_attribute.name.to_s] + .type end private @@ -68,22 +78,26 @@ module Ransack elsif (segments = str.split(/_/)).size > 1 remainder = [] found_assoc = nil - while remainder.unshift(segments.pop) && segments.size > 0 && !found_assoc do + 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) + 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} + klass.reflect_on_all_associations.detect { |a| a.name.to_s == str } end def join_dependency(relation) @@ -113,9 +127,9 @@ module Ransack 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 + string_joins = (buckets['string_join'] || []) + .map { |x| x.strip } + .uniq join_list = relation.send :custom_join_sql, (string_joins + join_nodes) @@ -133,13 +147,16 @@ module Ransack end def build_or_find_association(name, parent = @base, klass = nil) - found_association = @join_dependency.join_associations.detect do |assoc| + 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) + @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) diff --git a/lib/ransack/adapters/active_record/3.1/context.rb b/lib/ransack/adapters/active_record/3.1/context.rb index 8cecf22..a167c59 100644 --- a/lib/ransack/adapters/active_record/3.1/context.rb +++ b/lib/ransack/adapters/active_record/3.1/context.rb @@ -10,6 +10,8 @@ module Ransack JoinDependency = ::ActiveRecord::Associations::JoinDependency JoinPart = JoinDependency::JoinPart + # Redefine a few things for ActiveRecord 3.1. + def initialize(object, options = {}) super @arel_visitor = Arel::Visitors.visitor_for @engine @@ -23,10 +25,12 @@ module Ransack viz = Visitor.new relation = @object.where(viz.accept(search.base)) if search.sorts.any? - relation = relation.except(:order).reorder(viz.accept(search.sorts)) + relation = relation.except(:order) + .reorder(viz.accept(search.sorts)) end - opts[:distinct] ? relation.select( - "DISTINCT #{@klass.quoted_table_name}.*") : relation + opts[:distinct] ? + relation.select("DISTINCT #{@klass.quoted_table_name}.*") : + relation end def attribute_method?(str, klass = @klass) @@ -37,10 +41,15 @@ module Ransack 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('_')) + 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) + exists = attribute_method?( + remainder.join('_'), poly_class || found_assoc.klass + ) end end end @@ -74,11 +83,16 @@ module Ransack elsif (segments = str.split(/_/)).size > 1 remainder = [] found_assoc = nil - while remainder.unshift(segments.pop) && segments.size > 0 && !found_assoc do + 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) + join = build_or_find_association( + found_assoc.name, parent, klass + ) + parent, attr_name = get_parent_and_attribute_name( + remainder.join('_'), join + ) end end end @@ -89,7 +103,7 @@ module Ransack 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} + klass.reflect_on_all_associations.detect { |a| a.name.to_s == str } end def join_dependency(relation) @@ -119,11 +133,12 @@ module Ransack 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 + 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_list = relation.send :custom_join_ast, + relation.table.from(relation.table), string_joins join_dependency = JoinDependency.new( relation.klass, @@ -139,13 +154,16 @@ module Ransack end def build_or_find_association(name, parent = @base, klass = nil) - found_association = @join_dependency.join_associations.detect do |assoc| + 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) + @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) diff --git a/lib/ransack/adapters/active_record/3.2/context.rb b/lib/ransack/adapters/active_record/3.2/context.rb index 49e8589..c87de34 100644 --- a/lib/ransack/adapters/active_record/3.2/context.rb +++ b/lib/ransack/adapters/active_record/3.2/context.rb @@ -8,7 +8,7 @@ module Ransack module ActiveRecord class Context < ::Ransack::Context - # Redefine a few things that have changed with 3.2. + # Redefine a few things for ActiveRecord 3.2. def initialize(object, options = {}) super diff --git a/lib/ransack/adapters/active_record/base.rb b/lib/ransack/adapters/active_record/base.rb index 770b606..6ad24c0 100644 --- a/lib/ransack/adapters/active_record/base.rb +++ b/lib/ransack/adapters/active_record/base.rb @@ -17,8 +17,8 @@ module Ransack end def ransacker(name, opts = {}, &block) - self._ransackers = _ransackers.merge name.to_s => Ransacker.new( - self, name, opts, &block) + self._ransackers = _ransackers.merge name.to_s => Ransacker + .new(self, name, opts, &block) end def ransackable_attributes(auth_object = nil) @@ -26,7 +26,8 @@ module Ransack end def ransortable_attributes(auth_object = nil) - # Here so users can overwrite the attributes that show up in the sort_select + # Here so users can overwrite the attributes + # that show up in the sort_select ransackable_attributes(auth_object) end diff --git a/lib/ransack/constants.rb b/lib/ransack/constants.rb index 77c1147..b658d99 100644 --- a/lib/ransack/constants.rb +++ b/lib/ransack/constants.rb @@ -95,6 +95,5 @@ module Ransack unescaped.to_s.gsub(/([\\|\%|.])/, '\\\\\\1') end end - end end diff --git a/lib/ransack/context.rb b/lib/ransack/context.rb index c395010..b3e2e19 100644 --- a/lib/ransack/context.rb +++ b/lib/ransack/context.rb @@ -61,7 +61,9 @@ module Ransack obj elsif obj.respond_to? :klass obj.klass - elsif obj.respond_to? :base_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}" @@ -148,5 +150,9 @@ module Ransack def sortable_attributes(str = '') traverse(str).ransortable_attributes(auth_object) end + + def searchable_associations(str = '') + traverse(str).ransackable_associations(auth_object) + end end end diff --git a/lib/ransack/helpers/form_builder.rb b/lib/ransack/helpers/form_builder.rb index 7348a80..57ded9d 100644 --- a/lib/ransack/helpers/form_builder.rb +++ b/lib/ransack/helpers/form_builder.rb @@ -1,6 +1,4 @@ require 'action_view' -require 'simple_form' if - (ENV['RANSACK_FORM_BUILDER'] || '').match('SimpleForm') require 'simple_form' if (ENV['RANSACK_FORM_BUILDER'] || '').match('SimpleForm') @@ -109,7 +107,12 @@ module Ransack def predicate_select(options = {}, html_options = {}) options[:compounds] = true if options[:compounds].nil? - default = options.delete(:default) || 'cont' + if ::ActiveRecord::VERSION::STRING >= "4" + default = options.delete(:default) || 'cont' + else + default = options.delete(:default) || 'eq' + end + keys = options[:compounds] ? Predicate.names : Predicate.names.reject { |k| k.match(/_(any|all)$/) } if only = options[:only] diff --git a/lib/ransack/naming.rb b/lib/ransack/naming.rb index 2fd44e5..d1d9e45 100644 --- a/lib/ransack/naming.rb +++ b/lib/ransack/naming.rb @@ -23,7 +23,8 @@ module Ransack end class Name < String - attr_reader :singular, :plural, :element, :collection, :partial_path, :human, :param_key, :route_key, :i18n_key + attr_reader :singular, :plural, :element, :collection, :partial_path, + :human, :param_key, :route_key, :i18n_key alias_method :cache_key, :collection def initialize diff --git a/lib/ransack/nodes/attribute.rb b/lib/ransack/nodes/attribute.rb index cf44099..08f7ee8 100644 --- a/lib/ransack/nodes/attribute.rb +++ b/lib/ransack/nodes/attribute.rb @@ -52,4 +52,4 @@ module Ransack end end -end \ No newline at end of file +end diff --git a/lib/ransack/nodes/condition.rb b/lib/ransack/nodes/condition.rb index 04adb4a..e1a7e0b 100644 --- a/lib/ransack/nodes/condition.rb +++ b/lib/ransack/nodes/condition.rb @@ -19,7 +19,8 @@ module Ransack m: combinator, v: predicate.wants_array ? Array(values) : [values] ) - # TODO: Figure out what to do with multiple types of attributes, if anything. + # TODO: Figure out what to do with multiple types of attributes, + # if anything. # Tempted to go with "garbage in, garbage out" on this one predicate.validate(condition.values, condition.default_type) ? condition : nil @@ -208,14 +209,14 @@ module Ransack def inspect data = [ - ['attributes', a.try(:map, &:name)], - ['predicate', p], - ['combinator', m], - ['values', v.try(:map, &:value)] - ] - .reject { |e| e[1].blank? } - .map { |v| "#{v[0]}: #{v[1]}" } - .join(', ') + ['attributes', a.try(:map, &:name)], + ['predicate', p], + ['combinator', m], + ['values', v.try(:map, &:value)] + ] + .reject { |e| e[1].blank? } + .map { |v| "#{v[0]}: #{v[1]}" } + .join(', ') "Condition <#{data}>" end @@ -228,4 +229,4 @@ module Ransack end end -end \ No newline at end of file +end diff --git a/lib/ransack/nodes/grouping.rb b/lib/ransack/nodes/grouping.rb index d1e1b60..0239c8b 100644 --- a/lib/ransack/nodes/grouping.rb +++ b/lib/ransack/nodes/grouping.rb @@ -129,10 +129,9 @@ module Ransack when /^(g|c|m|groupings|conditions|combinator)=?$/ true else - name. - split(/_and_|_or_/). - select { |n| !@context.attribute_method?(n) }. - empty? + name.split(/_and_|_or_/) + .select { |n| !@context.attribute_method?(n) } + .empty? end end @@ -191,7 +190,6 @@ module Ransack Predicate.detect_and_strip_from_string!(string) string end - end end -end \ No newline at end of file +end diff --git a/lib/ransack/nodes/node.rb b/lib/ransack/nodes/node.rb index fdd4670..e614e9c 100644 --- a/lib/ransack/nodes/node.rb +++ b/lib/ransack/nodes/node.rb @@ -31,4 +31,4 @@ module Ransack end end -end \ No newline at end of file +end diff --git a/lib/ransack/nodes/sort.rb b/lib/ransack/nodes/sort.rb index 31fb92e..cd0453c 100644 --- a/lib/ransack/nodes/sort.rb +++ b/lib/ransack/nodes/sort.rb @@ -41,4 +41,4 @@ module Ransack end end -end \ No newline at end of file +end diff --git a/lib/ransack/nodes/value.rb b/lib/ransack/nodes/value.rb index 80450c6..41173bd 100644 --- a/lib/ransack/nodes/value.rb +++ b/lib/ransack/nodes/value.rb @@ -107,4 +107,4 @@ module Ransack end end end -end \ No newline at end of file +end diff --git a/lib/ransack/predicate.rb b/lib/ransack/predicate.rb index 451fa2f..944eaae 100644 --- a/lib/ransack/predicate.rb +++ b/lib/ransack/predicate.rb @@ -29,8 +29,9 @@ module Ransack end def name_from_attribute_name(attribute_name) - names_by_decreasing_length. - detect { |p| attribute_name.to_s.match(/_#{p}$/) } + names_by_decreasing_length.detect { + |p| attribute_name.to_s.match(/_#{p}$/) + } end def for_attribute_name(attribute_name) @@ -75,4 +76,4 @@ module Ransack end end -end \ No newline at end of file +end diff --git a/lib/ransack/ransacker.rb b/lib/ransack/ransacker.rb index f0a8490..a677880 100644 --- a/lib/ransack/ransacker.rb +++ b/lib/ransack/ransacker.rb @@ -21,4 +21,4 @@ module Ransack end end -end \ No newline at end of file +end diff --git a/lib/ransack/translate.rb b/lib/ransack/translate.rb index f029978..ca837ae 100644 --- a/lib/ransack/translate.rb +++ b/lib/ransack/translate.rb @@ -104,7 +104,11 @@ module Ransack end def self.i18n_key(klass) - klass.model_name.i18n_key + if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0 + klass.model_name.i18n_key.to_s.tr('.', '/') + else + klass.model_name.i18n_key.to_s + end end end end diff --git a/ransack.gemspec b/ransack.gemspec index 0713181..fd28726 100644 --- a/ransack.gemspec +++ b/ransack.gemspec @@ -15,9 +15,9 @@ Gem::Specification.new do |s| s.rubyforge_project = "ransack" - s.add_dependency 'actionpack', '>= 4.0' - s.add_dependency 'activerecord', '>= 4.0' - s.add_dependency 'activesupport', '>= 4.0' + s.add_dependency 'actionpack', '>= 3.0' + s.add_dependency 'activerecord', '>= 3.0' + s.add_dependency 'activesupport', '>= 3.0' s.add_dependency 'i18n' # s.add_dependency 'polyamorous', '~> 0.6.0' s.add_development_dependency 'rspec', '~> 2.8.0' diff --git a/spec/blueprints/people.rb b/spec/blueprints/people.rb index a86fd43..5fc983a 100644 --- a/spec/blueprints/people.rb +++ b/spec/blueprints/people.rb @@ -5,4 +5,4 @@ Person.blueprint do only_sort only_search only_admin -end \ No newline at end of file +end diff --git a/spec/console.rb b/spec/console.rb index 1cd0d16..3dd9ebc 100644 --- a/spec/console.rb +++ b/spec/console.rb @@ -19,4 +19,3 @@ Sham.define do end Schema.create - diff --git a/spec/ransack/adapters/active_record/base_spec.rb b/spec/ransack/adapters/active_record/base_spec.rb index 086f337..f2f39bc 100644 --- a/spec/ransack/adapters/active_record/base_spec.rb +++ b/spec/ransack/adapters/active_record/base_spec.rb @@ -37,6 +37,7 @@ module Ransack # ransacker :doubled_name do |parent| # Arel::Nodes::InfixOperation.new('||', parent.table[:name], parent.table[:name]) # end + it 'creates ransack attributes' do s = Person.search(reversed_name_eq: 'htimS cirA') s.result.should have(1).person @@ -60,18 +61,20 @@ module Ransack s.result.count.should eq 1 end if defined?(Arel::Nodes::InfixOperation) && sane_adapter? - it "should remove empty key value pairs from the params hash" do - s = Person.search(children_reversed_name_eq: '') - s.result.to_sql.should_not match /LEFT OUTER JOIN/ - end + if ::ActiveRecord::VERSION::STRING >= "4" + it "should remove empty key value pairs from the params hash" do + s = Person.search(children_reversed_name_eq: '') + s.result.to_sql.should_not match /LEFT OUTER JOIN/ + end - it "should keep proper key value pairs in the params hash" do - s = Person.search(children_reversed_name_eq: 'Testing') - s.result.to_sql.should match /LEFT OUTER JOIN/ - end + it "should keep proper key value pairs in the params hash" do + s = Person.search(children_reversed_name_eq: 'Testing') + s.result.to_sql.should match /LEFT OUTER JOIN/ + end - it "should function correctly when nil is passed in" do - s = Person.search(nil) + it "should function correctly when nil is passed in" do + s = Person.search(nil) + end end it "should function correctly when using fields with dots in them" do @@ -219,4 +222,4 @@ module Ransack end end end -end \ No newline at end of file +end diff --git a/spec/ransack/adapters/active_record/context_spec.rb b/spec/ransack/adapters/active_record/context_spec.rb index a309cae..9960633 100644 --- a/spec/ransack/adapters/active_record/context_spec.rb +++ b/spec/ransack/adapters/active_record/context_spec.rb @@ -48,4 +48,4 @@ module Ransack end end end -end \ No newline at end of file +end diff --git a/spec/ransack/configuration_spec.rb b/spec/ransack/configuration_spec.rb index 3195cbb..5bd2827 100644 --- a/spec/ransack/configuration_spec.rb +++ b/spec/ransack/configuration_spec.rb @@ -65,4 +65,4 @@ module Ransack Ransack.predicates.should_not have_key 'test_array_predicate_all' end end -end \ No newline at end of file +end diff --git a/spec/ransack/dependencies_spec.rb b/spec/ransack/dependencies_spec.rb index 408339a..8025f28 100644 --- a/spec/ransack/dependencies_spec.rb +++ b/spec/ransack/dependencies_spec.rb @@ -1,6 +1,8 @@ -#describe 'Ransack' do -# it 'can be required without errors' do -# output = `bundle exec ruby -e "require 'ransack'" 2>&1` -# output.should be_empty -# end -#end +unless ::ActiveRecord::VERSION::STRING >= "4" + describe 'Ransack' do + it 'can be required without errors' do + output = `bundle exec ruby -e "require 'ransack'" 2>&1` + output.should be_empty + end + end +end diff --git a/spec/ransack/helpers/form_builder_spec.rb b/spec/ransack/helpers/form_builder_spec.rb index 8fb8cbc..8639ec7 100644 --- a/spec/ransack/helpers/form_builder_spec.rb +++ b/spec/ransack/helpers/form_builder_spec.rb @@ -55,7 +55,11 @@ module Ransack describe '#sort_link' do it 'sort_link for ransack attribute' do sort_link = @f.sort_link :name, controller: 'people' - sort_link.should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/ + if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./ + sort_link.should match /people\?q%5Bs%5D=name\+asc/ + else + sort_link.should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/ + end sort_link.should match /sort_link/ sort_link.should match /Full Name<\/a>/ end diff --git a/spec/ransack/helpers/form_helper_spec.rb b/spec/ransack/helpers/form_helper_spec.rb index 56b5d8c..68525b2 100644 --- a/spec/ransack/helpers/form_helper_spec.rb +++ b/spec/ransack/helpers/form_helper_spec.rb @@ -33,48 +33,63 @@ module Ransack controller: 'people' ) } - it { should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/ } + it { should match( + if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./ + /people\?q%5Bs%5D=name\+asc/ + else + /people\?q(%5B|\[)s(%5D|\])=name\+asc/ + end) + } it { should match /sort_link desc/ } it { should match /Full Name ▼/ } end describe '#sort_link with default search_key defined as symbol' do - subject { @controller.view_context. - sort_link( - Person.search({ sorts: ['name desc'] }, search_key: :people_search), - :name, - controller: 'people' + subject { @controller. + view_context.sort_link( + Person.search({ :sorts => ['name desc'] }, :search_key => :people_search), + :name, :controller => 'people' ) } - it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ } + it { should match( + if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./ + /people\?people_search%5Bs%5D=name\+asc/ + else + /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ + end) + } end describe '#sort_link with default search_key defined as string' do - subject { @controller.view_context. - sort_link( - Person.search({ sorts: ['name desc'] }, search_key: 'people_search'), - :name, - controller: 'people' + subject { + @controller.view_context.sort_link( + Person.search({ :sorts => ['name desc'] }, :search_key => 'people_search'), + :name, :controller => 'people' ) } - it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ } + it { should match( + if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./ + /people\?people_search%5Bs%5D=name\+asc/ + else + /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ + end) + } end context 'view has existing parameters' do before do - @controller.view_context. - params.merge!({ exist: 'existing' }) + @controller.view_context.params.merge!({ :exist => 'existing' }) end describe '#sort_link should not remove existing params' do subject { - @controller.view_context. - sort_link( - Person.search({ sorts: ['name desc'] }, search_key: 'people_search'), - :name, - controller: 'people' - ) + @controller.view_context.sort_link( + Person.search({ :sorts => ['name desc'] }, :search_key => 'people_search'), + :name, :controller => 'people' + ) + } + it { + should match /exist\=existing/ } - it { should match /exist\=existing/ } end end end diff --git a/spec/ransack/predicate_spec.rb b/spec/ransack/predicate_spec.rb index 186d2bb..42d6b9f 100644 --- a/spec/ransack/predicate_spec.rb +++ b/spec/ransack/predicate_spec.rb @@ -42,17 +42,15 @@ module Ransack end describe 'cont' do - + it_has_behavior 'wildcard escaping', :name_cont, - ( - if ActiveRecord::Base.connection.adapter_name == "PostgreSQL" + (if ActiveRecord::Base.connection.adapter_name == "PostgreSQL" /"people"."name" ILIKE '%\\%\\._\\\\%'/ elsif ActiveRecord::Base.connection.adapter_name == "Mysql2" /`people`.`name` LIKE '%\\\\%\\\\._\\\\\\\\%'/ else - /"people"."name" LIKE '%%._\\%'/ - end - ) do + /"people"."name" LIKE '%%._\\%'/ + end) do subject { @s } end @@ -65,15 +63,13 @@ module Ransack describe 'not_cont' do it_has_behavior 'wildcard escaping', :name_not_cont, - ( - if ActiveRecord::Base.connection.adapter_name == "PostgreSQL" + (if ActiveRecord::Base.connection.adapter_name == "PostgreSQL" /"people"."name" NOT ILIKE '%\\%\\._\\\\%'/ elsif ActiveRecord::Base.connection.adapter_name == "Mysql2" /`people`.`name` NOT LIKE '%\\\\%\\\\._\\\\\\\\%'/ else - /"people"."name" NOT LIKE '%%._\\%'/ - end - ) do + /"people"."name" NOT LIKE '%%._\\%'/ + end) do subject { @s } end diff --git a/spec/ransack/search_spec.rb b/spec/ransack/search_spec.rb index c9f6dab..bf185db 100644 --- a/spec/ransack/search_spec.rb +++ b/spec/ransack/search_spec.rb @@ -89,13 +89,11 @@ module Ransack it 'accepts "attributes" hashes for conditions' do search = Search.new(Person, - c: { - '0' => { a: ['name'], p: 'eq', v: ['Ernie'] }, - '1' => { - a: ['children_name', 'parent_name'], - p: 'eq', v: ['Ernie'], m: 'or' - } - } + :c => { + '0' => { :a => ['name'], :p => 'eq', :v => ['Ernie'] }, + '1' => { :a => ['children_name', 'parent_name'], + :p => 'eq', :v => ['Ernie'], :m => 'or' } + } ) conditions = search.base.conditions conditions.should have(2).items @@ -105,8 +103,7 @@ module Ransack it 'creates conditions for custom predicates that take arrays' do Ransack.configure do |config| - config.add_predicate 'ary_pred', - wants_array: true + config.add_predicate 'ary_pred', :wants_array => true end search = Search.new(Person, name_ary_pred: ['Ernie', 'Bert']) @@ -183,18 +180,42 @@ module Ransack second.should match /#{children_people_name_field} = 'Bert'/ end - it 'returns distinct records when passed distinct: true' do - search = Search.new( - Person, g: [ - { m: 'or', - comments_body_cont: 'e', - articles_comments_body_cont: 'e' - } - ] - ) - search.result.load.should have(9000).items - search.result(distinct: true).should have(10).items - search.result.load.uniq.should eq search.result(distinct: true).load + if ::ActiveRecord::VERSION::STRING >= "4" + it 'returns distinct records when passed distinct: true' do + search = Search.new( + Person, g: [ + { m: 'or', + comments_body_cont: 'e', + articles_comments_body_cont: 'e' + } + ] + ) + search.result.load.should have(9000).items + search.result(distinct: true).should have(10).items + search.result.load.uniq.should eq search.result(distinct: true).load + end + else + it 'returns distinct records when passed :distinct => true' do + search = Search.new( + Person, :g => [ + { :m => 'or', + :comments_body_cont => 'e', + :articles_comments_body_cont => 'e' + } + ] + ) + if ActiveRecord::VERSION::MAJOR == 3 + all_or_load, uniq_or_distinct = :all, :uniq + else + all_or_load, uniq_or_distinct = :load, :distinct + end + search.result.send(all_or_load). + should have(920).items + search.result(:distinct => true). + should have(330).items + search.result.send(all_or_load).send(uniq_or_distinct). + should eq search.result(:distinct => true).send(all_or_load) + end end end diff --git a/spec/ransack/translate_spec.rb b/spec/ransack/translate_spec.rb index 0a4d181..4ce2a21 100644 --- a/spec/ransack/translate_spec.rb +++ b/spec/ransack/translate_spec.rb @@ -6,9 +6,7 @@ module Ransack describe '.attribute' do it 'translate namespaced attribute like AR does' do ar_translation = ::Namespace::Article.human_attribute_name(:title) - ransack_translation = Ransack::Translate.attribute( - :title, :context => ::Namespace::Article.search.context - ) + ransack_translation = Ransack::Translate.attribute(:title, :context => ::Namespace::Article.search.context) ransack_translation.should eq ar_translation end end diff --git a/spec/support/schema.rb b/spec/support/schema.rb index edd4449..de24f84 100644 --- a/spec/support/schema.rb +++ b/spec/support/schema.rb @@ -23,7 +23,11 @@ else end class Person < ActiveRecord::Base - default_scope { order(id: :desc) } + if ActiveRecord::VERSION::MAJOR == 3 + default_scope order('id DESC') + else + default_scope { order(id: :desc) } + end belongs_to :parent, class_name: 'Person', foreign_key: :parent_id has_many :children, class_name: 'Person', foreign_key: :parent_id has_many :articles @@ -57,6 +61,22 @@ class Person < ActiveRecord::Base column_names + _ransackers.keys - ['only_search', 'only_admin'] end end + + def self.ransackable_attributes(auth_object = nil) + if auth_object == :admin + column_names + _ransackers.keys - ['only_sort'] + else + column_names + _ransackers.keys - ['only_sort', 'only_admin'] + end + end + + def self.ransortable_attributes(auth_object = nil) + if auth_object == :admin + column_names + _ransackers.keys - ['only_search'] + else + column_names + _ransackers.keys - ['only_search', 'only_admin'] + end + end end class Article < ActiveRecord::Base @@ -72,6 +92,12 @@ module Namespace end end +module Namespace + class Article < ::Article + + end +end + class Comment < ActiveRecord::Base belongs_to :article belongs_to :person @@ -128,6 +154,7 @@ module Schema t.string :notable_type t.string :note end + end 10.times do @@ -148,6 +175,5 @@ module Schema Comment.make( body: 'First post!', article: Article.make(title: 'Hello, world!') ) - - end + end end