diff --git a/Gemfile.lock b/Gemfile.lock index 61d2b1c..43e6ca0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,105 +1,139 @@ PATH remote: . specs: - activerecord_search (1.2) - activerecord (>= 4.0.0) - rails (>= 4.0.0) + activerecord_search (1.3.1) + activerecord (~> 5.2.0) + rails (~> 5.2.0) GEM remote: https://rubygems.org/ specs: - actionmailer (4.1.4) - actionpack (= 4.1.4) - actionview (= 4.1.4) - mail (~> 2.5.4) - actionpack (4.1.4) - actionview (= 4.1.4) - activesupport (= 4.1.4) - rack (~> 1.5.2) - rack-test (~> 0.6.2) - actionview (4.1.4) - activesupport (= 4.1.4) + actioncable (5.2.3) + actionpack (= 5.2.3) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + actionmailer (5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.2.3) + actionview (= 5.2.3) + activesupport (= 5.2.3) + rack (~> 2.0) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.2.3) + activesupport (= 5.2.3) builder (~> 3.1) - erubis (~> 2.7.0) - activemodel (4.1.4) - activesupport (= 4.1.4) - builder (~> 3.1) - activerecord (4.1.4) - activemodel (= 4.1.4) - activesupport (= 4.1.4) - arel (~> 5.0.0) - activesupport (4.1.4) - i18n (~> 0.6, >= 0.6.9) - json (~> 1.7, >= 1.7.7) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.2.3) + activesupport (= 5.2.3) + globalid (>= 0.3.6) + activemodel (5.2.3) + activesupport (= 5.2.3) + activerecord (5.2.3) + activemodel (= 5.2.3) + activesupport (= 5.2.3) + arel (>= 9.0) + activestorage (5.2.3) + actionpack (= 5.2.3) + activerecord (= 5.2.3) + marcel (~> 0.3.1) + activesupport (5.2.3) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) minitest (~> 5.1) - thread_safe (~> 0.1) tzinfo (~> 1.1) - arel (5.0.1.20140414130214) - builder (3.2.2) - diff-lcs (1.2.5) - erubis (2.7.0) - hike (1.2.3) - i18n (0.6.11) - json (1.8.1) - mail (2.5.4) - mime-types (~> 1.16) - treetop (~> 1.4.8) - mime-types (1.25.1) - minitest (5.4.0) - multi_json (1.10.1) - polyglot (0.3.5) - rack (1.5.2) - rack-test (0.6.2) - rack (>= 1.0) - rails (4.1.4) - actionmailer (= 4.1.4) - actionpack (= 4.1.4) - actionview (= 4.1.4) - activemodel (= 4.1.4) - activerecord (= 4.1.4) - activesupport (= 4.1.4) - bundler (>= 1.3.0, < 2.0) - railties (= 4.1.4) - sprockets-rails (~> 2.0) - railties (4.1.4) - actionpack (= 4.1.4) - activesupport (= 4.1.4) + arel (9.0.0) + builder (3.2.3) + concurrent-ruby (1.1.5) + crass (1.0.4) + diff-lcs (1.3) + erubi (1.8.0) + globalid (0.4.2) + activesupport (>= 4.2.0) + i18n (1.6.0) + concurrent-ruby (~> 1.0) + loofah (2.2.3) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mail (2.7.1) + mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) + method_source (0.9.2) + mimemagic (0.3.3) + mini_mime (1.0.2) + mini_portile2 (2.4.0) + minitest (5.11.3) + nio4r (2.4.0) + nokogiri (1.10.3) + mini_portile2 (~> 2.4.0) + rack (2.0.7) + rack-test (1.1.0) + rack (>= 1.0, < 3) + rails (5.2.3) + actioncable (= 5.2.3) + actionmailer (= 5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) + activemodel (= 5.2.3) + activerecord (= 5.2.3) + activestorage (= 5.2.3) + activesupport (= 5.2.3) + bundler (>= 1.3.0) + railties (= 5.2.3) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.4) + loofah (~> 2.2, >= 2.2.2) + railties (5.2.3) + actionpack (= 5.2.3) + activesupport (= 5.2.3) + method_source rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) - rake (10.3.2) - rspec-core (3.0.2) - rspec-support (~> 3.0.0) - rspec-expectations (3.0.2) + thor (>= 0.19.0, < 2.0) + rake (12.3.2) + rspec-core (3.8.2) + rspec-support (~> 3.8.0) + rspec-expectations (3.8.4) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.0.0) - rspec-mocks (3.0.2) - rspec-support (~> 3.0.0) - rspec-rails (3.0.1) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 3.0.0) - rspec-expectations (~> 3.0.0) - rspec-mocks (~> 3.0.0) - rspec-support (~> 3.0.0) - rspec-support (3.0.2) - sprockets (2.12.1) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.1.3) - actionpack (>= 3.0) - activesupport (>= 3.0) - sprockets (~> 2.8) - thor (0.19.1) - thread_safe (0.3.4) - tilt (1.4.1) - treetop (1.4.15) - polyglot - polyglot (>= 0.3.1) - tzinfo (1.2.1) + rspec-support (~> 3.8.0) + rspec-mocks (3.8.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.8.0) + rspec-rails (4.0.0.beta2) + actionpack (>= 4.2) + activesupport (>= 4.2) + railties (>= 4.2) + rspec-core (~> 3.8) + rspec-expectations (~> 3.8) + rspec-mocks (~> 3.8) + rspec-support (~> 3.8) + rspec-support (3.8.2) + sprockets (3.7.2) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.1) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + sqlite3 (1.3.13) + thor (0.20.3) + thread_safe (0.3.6) + tzinfo (1.2.5) thread_safe (~> 0.1) + websocket-driver (0.7.1) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.4) PLATFORMS ruby @@ -107,3 +141,7 @@ PLATFORMS DEPENDENCIES activerecord_search! rspec-rails (>= 3.0.0.beta) + sqlite3 (~> 1.3.6) + +BUNDLED WITH + 2.0.2 diff --git a/activerecord_search.gemspec b/activerecord_search.gemspec index f01f4d6..cc76052 100644 --- a/activerecord_search.gemspec +++ b/activerecord_search.gemspec @@ -1,17 +1,18 @@ Gem::Specification.new do |s| s.name = 'activerecord_search' - s.version = '1.2' - s.date = Date.today.to_s + s.version = '1.3.1' + s.date = '2019-07-16' s.summary = "An easy way to write LIKE / ILIKE queries for Active Record models" s.description = "Extends the ActiveRecord predicate builder to allow writing LIKE/ILIKE queries without writing raw SQL" - s.authors = ["Tony Novak"] + s.authors = ["Tony Novak", "Nick Hance"] s.email = 'tony@amitree.com' s.files = Dir["{lib,spec,vendor}/**/*", "[A-Z]*"] - ["Gemfile.lock"] s.homepage = 'http://rubygems.org/gems/activerecord_search' s.license = 'MIT' - s.add_runtime_dependency 'activerecord', '>= 4.0.0' - s.add_runtime_dependency 'rails', '>= 4.0.0' + s.add_runtime_dependency 'activerecord', '~> 5.2.0' + s.add_runtime_dependency 'rails', '~> 5.2.0' + s.add_development_dependency 'sqlite3', '~> 1.3.6' s.add_development_dependency 'rspec-rails', '>= 3.0.0.beta' end diff --git a/lib/activerecord_search.rb b/lib/activerecord_search.rb index 9c8fe86..3ca0c3c 100644 --- a/lib/activerecord_search.rb +++ b/lib/activerecord_search.rb @@ -1,4 +1,5 @@ require 'activerecord_search/term' +require 'activerecord_search/predicate_handler' require 'activerecord_search/railtie' def Search(condition) diff --git a/lib/activerecord_search/predicate_handler.rb b/lib/activerecord_search/predicate_handler.rb new file mode 100644 index 0000000..e4d0f79 --- /dev/null +++ b/lib/activerecord_search/predicate_handler.rb @@ -0,0 +1,11 @@ +module ActiverecordSearch + module PredicateHandler + def predicate_builder + return @local_predicate_builder if @local_predicate_builder + @local_predicate_builder = super + @local_predicate_builder.register_handler(::ActiverecordSearch::Term, ->(attribute, search_term) { search_term.match(attribute) }) + + @local_predicate_builder + end + end +end diff --git a/lib/activerecord_search/railtie.rb b/lib/activerecord_search/railtie.rb index eb87d09..36ecb0f 100644 --- a/lib/activerecord_search/railtie.rb +++ b/lib/activerecord_search/railtie.rb @@ -1,7 +1,9 @@ module ActiverecordSearch class Railtie < ::Rails::Railtie initializer "PredicateBuilder" do - ActiveRecord::PredicateBuilder.register_handler(::ActiverecordSearch::Term, ->(attribute, search_term) { search_term.match(attribute) }) + ActiveSupport.on_load(:active_record) do + ActiveRecord::Base.singleton_class.send :prepend, ActiverecordSearch::PredicateHandler + end end end end diff --git a/lib/activerecord_search/term.rb b/lib/activerecord_search/term.rb index 6843093..d78726e 100644 --- a/lib/activerecord_search/term.rb +++ b/lib/activerecord_search/term.rb @@ -6,6 +6,8 @@ def initialize(condition) raise "Condition can't be nil" when Hash key, value = condition.first if condition.length == 1 + raise "Condition can't be nil" if key.nil? + case key.to_sym when :starts_with "#{value}%" diff --git a/spec/lib/activerecord_search_spec.rb b/spec/lib/activerecord_search_spec.rb index 73db804..c0fef0e 100644 --- a/spec/lib/activerecord_search_spec.rb +++ b/spec/lib/activerecord_search_spec.rb @@ -1,14 +1,20 @@ require 'spec_helper' -class User < ActiveRecord::Base -end - describe ActiverecordSearch do - let(:relation) { ActiveRecord::Relation.new(User, Arel::Table.new('users')) } + if Rails::VERSION::MINOR > 1 + let(:relation) { ActiveRecord::Relation.new(User, table: Arel::Table.new('users'), predicate_builder: User.predicate_builder) } + else + let(:relation) { ActiveRecord::Relation.new(User, Arel::Table.new('users'), User.predicate_builder) } + end shared_examples_for 'generates the correct query' do |condition, attribute, pattern| - let(:arel_nodes) { relation.where(condition).where_values } - let(:arel_node) { arel_nodes.first } + let(:arel_nodes) { relation.where(condition).where_clause.ast.children } + + if Rails::VERSION::MINOR > 1 + let(:arel_node) { arel_nodes.first } + else + let(:arel_node) { arel_nodes.first.expr } + end it 'returns a Arel::Nodes::Matches node' do expect(arel_nodes.length).to eq 1 @@ -20,7 +26,7 @@ class User < ActiveRecord::Base end it 'uses the right pattern' do - expect(arel_node.right).to eq pattern + expect(arel_node.right.val).to eq pattern end end @@ -48,13 +54,13 @@ class User < ActiveRecord::Base describe 'exceptions' do it 'should raise if an empty hash is passed' do - expect { Search({}) }.to raise_error + expect { Search({}) }.to raise_error(RuntimeError) end it 'should raise if multiple hash keys are passed' do - expect { Search({starts_with: 'a', ends_with: 'b'}) }.to raise_error + expect { Search({starts_with: 'a', ends_with: 'b'}) }.to raise_error(RuntimeError) end it 'should raise if an invalid hash key is passed' do - expect { Search({foo: 'bar'}) }.to raise_error + expect { Search({foo: 'bar'}) }.to raise_error(RuntimeError) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6df101e..a0f3291 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,15 @@ require 'rails/all' require 'activerecord_search' +ActiveRecord::Base.establish_connection( + adapter: 'sqlite3', + database: ':memory:' +) + ActiverecordSearch::Railtie.run_initializers + +ActiveRecord::Base.connection.create_table(:users) do |t| + t.string :foo +end +class User < ActiveRecord::Base +end