mincer 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/Gemfile +2 -1
  4. data/README.md +111 -64
  5. data/lib/mincer/action_view/sort_helper.rb +7 -7
  6. data/lib/mincer/base.rb +1 -1
  7. data/lib/mincer/config.rb +29 -0
  8. data/lib/mincer/core_ext/string.rb +5 -0
  9. data/lib/mincer/processors/cache_digest/processor.rb +54 -0
  10. data/lib/mincer/processors/helpers.rb +15 -0
  11. data/lib/mincer/processors/pagination/processor.rb +63 -0
  12. data/lib/mincer/processors/pg_json_dumper/processor.rb +69 -0
  13. data/lib/mincer/processors/pg_search/processor.rb +148 -0
  14. data/lib/mincer/processors/pg_search/sanitizer.rb +61 -0
  15. data/lib/mincer/processors/pg_search/search_engines/array.rb +41 -0
  16. data/lib/mincer/processors/pg_search/search_engines/base.rb +56 -0
  17. data/lib/mincer/processors/pg_search/search_engines/fulltext.rb +58 -0
  18. data/lib/mincer/processors/pg_search/search_engines/trigram.rb +41 -0
  19. data/lib/mincer/processors/pg_search/search_statement.rb +31 -0
  20. data/lib/mincer/processors/sorting/processor.rb +113 -0
  21. data/lib/mincer/version.rb +1 -1
  22. data/lib/mincer.rb +31 -31
  23. data/mincer.gemspec +0 -2
  24. data/spec/lib/mincer/action_view/sort_helper_spec.rb +11 -0
  25. data/spec/lib/mincer/base_spec.rb +15 -0
  26. data/spec/lib/mincer/config_spec.rb +7 -0
  27. data/spec/lib/{processors/cache_digest_spec.rb → mincer/processors/cache_digest/processor_spec.rb} +2 -9
  28. data/spec/lib/{processors/paginate_spec.rb → mincer/processors/pagination/processor_spec.rb} +43 -17
  29. data/spec/lib/{processors/pg_json_dumper_spec.rb → mincer/processors/pg_json_dumper/processor_spec.rb} +2 -6
  30. data/spec/lib/mincer/processors/pg_search/processor_spec.rb +268 -0
  31. data/spec/lib/mincer/processors/pg_search/sanitizer_spec.rb +38 -0
  32. data/spec/lib/mincer/processors/pg_search/search_engines/array_spec.rb +83 -0
  33. data/spec/lib/mincer/processors/pg_search/search_engines/fulltext_spec.rb +101 -0
  34. data/spec/lib/mincer/processors/pg_search/search_engines/trigram_spec.rb +91 -0
  35. data/spec/lib/mincer/processors/sorting/processor_spec.rb +181 -0
  36. data/spec/mincer_config.rb +38 -0
  37. data/spec/spec_helper.rb +40 -4
  38. data/spec/support/postgres_adapter.rb +12 -3
  39. data/spec/support/sqlite3_adapter.rb +3 -0
  40. metadata +42 -45
  41. data/lib/mincer/processors/cache_digest.rb +0 -50
  42. data/lib/mincer/processors/paginate.rb +0 -41
  43. data/lib/mincer/processors/pg_json_dumper.rb +0 -51
  44. data/lib/mincer/processors/search.rb +0 -34
  45. data/lib/mincer/processors/sort.rb +0 -59
  46. data/spec/lib/processors/search_spec.rb +0 -77
  47. data/spec/lib/processors/sort_spec.rb +0 -77
@@ -0,0 +1,148 @@
1
+ # This and all processors are heavily influenced by pg_search(https://github.com/Casecommons/pg_search)
2
+ module Mincer
3
+ module Processors
4
+ module PgSearch
5
+ class Processor
6
+ include ::Mincer::Processors::Helpers
7
+
8
+ def initialize(mincer)
9
+ @mincer, @args, @relation = mincer, mincer.args, mincer.relation
10
+ end
11
+
12
+ def apply
13
+ if Mincer.postgres?
14
+ @relation = apply_pg_search(@relation, @args)
15
+ else
16
+ @relation
17
+ end
18
+ end
19
+
20
+ def apply_pg_search(relation, args)
21
+ relation.where(conditions(args)).reorder(rank(args))
22
+ end
23
+
24
+ def conditions(args)
25
+ search_statements_conditions = search_statements.map do |search_statement|
26
+ conditions = pg_search_engines(args, search_statement).map do |pg_search_engine|
27
+ pg_search_engine.conditions
28
+ end.compact
29
+ join_expressions(conditions, options[:join_with] || :or)
30
+ end.compact
31
+ join_expressions(search_statements_conditions, options[:join_with] || :or).try(:to_sql)
32
+ end
33
+
34
+ def rank(args)
35
+ search_statements_conditions = search_statements.map do |search_statement|
36
+ conditions = pg_search_engines(args, search_statement).map do |pg_search_engine|
37
+ pg_search_engine.rank
38
+ end.compact
39
+ join_expressions(conditions, :+)
40
+ end.compact
41
+ rank = join_expressions(search_statements_conditions, :+).try(:to_sql)
42
+ "#{rank} DESC" if rank.present?
43
+ end
44
+
45
+ def pg_search_engines(args, search_statement)
46
+ Mincer.config.pg_search.engines.map do |engine_class|
47
+ engine_class.new(args, [search_statement])
48
+ end
49
+ end
50
+
51
+ def search_statements
52
+ @search_statements ||= params.any? { |param| param[:columns] } ? search_statements_from_params : default_search_statements
53
+ end
54
+
55
+ def search_statements_from_params
56
+ params.map do |param|
57
+ par = param.dup
58
+ SearchStatement.new(par.delete(:columns), search_statement_default_options(param[:engines]).merge(par))
59
+ end
60
+ end
61
+
62
+ # We use only text/string columns and avoid array
63
+ def default_search_statements
64
+ column_names = @relation.columns.reject do |column|
65
+ ![:string, :text].include?(column.type) || column.array
66
+ end.map do |column|
67
+ "#{@relation.table_name}.#{column.name}"
68
+ end
69
+ [SearchStatement.new(column_names, search_statement_default_options([:fulltext]).merge(engines: [:fulltext]))]
70
+ end
71
+
72
+ def params
73
+ Array.wrap(@mincer.send(:pg_search_params))
74
+ end
75
+
76
+ def options
77
+ @mincer.send(:pg_search_options)
78
+ end
79
+
80
+ def search_statement_default_options(engines)
81
+ (engines & [:fulltext, :trigram, :array]).inject({}) do |options, engine|
82
+ options = Mincer.config.pg_search.send("#{engine}_engine").merge(options)
83
+ options
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ module Options
90
+ extend ActiveSupport::Concern
91
+
92
+ def sort_by_rank
93
+ end
94
+
95
+ module ClassMethods
96
+ def skip_pg_search!
97
+ active_processors.delete(Mincer::Processors::PgSearch::Processor)
98
+ end
99
+
100
+ def skip_search!
101
+ skip_pg_search!
102
+ end
103
+
104
+ def pg_search(params, options = {})
105
+ class_eval <<-OPTIONS, __FILE__, __LINE__
106
+ def pg_search_params
107
+ @pg_search_params ||= #{params.inspect}
108
+ end
109
+ def pg_search_options
110
+ @pg_search_options ||= #{options.inspect}
111
+ end
112
+ OPTIONS
113
+ end
114
+ end
115
+
116
+ def pg_search_params
117
+ @pg_search_params ||= {}
118
+ end
119
+
120
+ def pg_search_options
121
+ @pg_search_options ||= {}
122
+ end
123
+ end
124
+
125
+ class Configuration
126
+ include ActiveSupport::Configurable
127
+ config_accessor :param_name do
128
+ 'pattern'
129
+ end
130
+ config_accessor :fulltext_engine do
131
+ { ignore_accent: true, any_word: false, dictionary: :simple, ignore_case: false }
132
+ end
133
+ config_accessor :trigram_engine do
134
+ { ignore_accent: true, threshold: 0.3 }
135
+ end
136
+ config_accessor :array_engine do
137
+ { ignore_accent: true, any_word: true }
138
+ end
139
+ config_accessor :engines do
140
+ [Mincer::PgSearch::SearchEngines::Fulltext, Mincer::PgSearch::SearchEngines::Array, Mincer::PgSearch::SearchEngines::Trigram]
141
+ end
142
+ end
143
+
144
+ end
145
+ end
146
+ end
147
+
148
+ ::Mincer.add_processor(:pg_search)
@@ -0,0 +1,61 @@
1
+ module Mincer
2
+ module Processors
3
+ module PgSearch
4
+ class Sanitizer
5
+ AVAILABLE_SANITIZERS = [:coalesce, :ignore_case, :ignore_accent]
6
+ attr_accessor :term, :sanitizers
7
+
8
+ def initialize(term, *sanitizers)
9
+ @term, @sanitizers = term, AVAILABLE_SANITIZERS & Array.wrap(sanitizers).flatten
10
+ end
11
+
12
+ def sanitize_column
13
+ @sanitized_column ||= sanitize(Arel.sql(@term))
14
+ end
15
+
16
+ def sanitize_string(options = {})
17
+ if sanitizers.empty?
18
+ return options[:quote] ? Mincer.connection.quote(@term) : @term
19
+ end
20
+ @sanitized_string ||= sanitize(@term)
21
+ end
22
+
23
+ def sanitize(node)
24
+ sanitizers.inject(node) do |query, sanitizer|
25
+ query = self.class.send(sanitizer, query)
26
+ query
27
+ end
28
+ end
29
+
30
+ def self.sanitize_column(term, *sanitizers)
31
+ new(term, *sanitizers).sanitize_column
32
+ end
33
+
34
+ def self.sanitize_string(term, *sanitizers)
35
+ new(term, *sanitizers).sanitize_string
36
+ end
37
+
38
+ def self.sanitize_string_quoted(term, *sanitizers)
39
+ new(term, *sanitizers).sanitize_string(quote: true)
40
+ end
41
+
42
+ def self.ignore_case(term)
43
+ Arel::Nodes::NamedFunction.new('lower', [term])
44
+ end
45
+
46
+ def self.ignore_accent(term)
47
+ Arel::Nodes::NamedFunction.new('unaccent', [term])
48
+ end
49
+
50
+ def self.coalesce(term, val = '')
51
+ if Mincer.pg_extension_installed?(:unaccent)
52
+ Arel::Nodes::NamedFunction.new('coalesce', [term, val])
53
+ else
54
+ term
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,41 @@
1
+ module Mincer
2
+ module PgSearch
3
+ module SearchEngines
4
+ class Array < Base
5
+
6
+ def conditions
7
+ return nil unless prepared_search_statements.any?
8
+ arel_group do
9
+ conditions = prepared_search_statements.map do |search_statement|
10
+ if search_statement.pattern = args[search_statement.param_name]
11
+ terms_delimiter = search_statement.options[:any_word] ? '&&' : '@>'
12
+ arel_group(Arel::Nodes::InfixOperation.new(terms_delimiter, document_for(search_statement), query_for(search_statement)))
13
+ end
14
+ end
15
+ join_expressions(conditions, :or)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def document_for(search_statement)
22
+ arel_group do
23
+ documents = search_statement.columns.map do |search_column|
24
+ Arel.sql(search_column + '::text[]')
25
+ end
26
+ join_expressions(documents, '||')
27
+ end
28
+ end
29
+
30
+ def query_for(search_statement)
31
+ normalized_pattern = search_statement.pattern.split(%r{\s|,}).uniq.reject(&:empty?).map do |item|
32
+ sanitize_string_quoted(item, search_statement.sanitizers).to_sql
33
+ end.join(',')
34
+ Arel.sql("ARRAY[#{normalized_pattern}]")
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,56 @@
1
+ module Mincer
2
+ module PgSearch
3
+ module SearchEngines
4
+ class Base
5
+ include ::Mincer::Processors::Helpers
6
+ attr_reader :args, :search_statements
7
+
8
+ def initialize(args, search_statements)
9
+ @args, @search_statements = ::ActiveSupport::HashWithIndifferentAccess.new(args), search_statements
10
+ end
11
+
12
+ def arel_group(sql_string = nil)
13
+ sql_string = yield if block_given?
14
+ arel_query = sql_string.is_a?(String) ? Arel.sql(sql_string) : sql_string
15
+ Arel::Nodes::Grouping.new(arel_query)
16
+ end
17
+
18
+ def sanitize_column(term, sanitizers)
19
+ ::Mincer::Processors::PgSearch::Sanitizer.sanitize_column(term, sanitizers)
20
+ end
21
+
22
+ def sanitize_string(term, sanitizers)
23
+ ::Mincer::Processors::PgSearch::Sanitizer.sanitize_string(term, sanitizers)
24
+ end
25
+
26
+ def sanitize_string_quoted(term, sanitizers)
27
+ ::Mincer::Processors::PgSearch::Sanitizer.sanitize_string_quoted(term, sanitizers)
28
+ end
29
+
30
+ def search_engine_statements
31
+ @search_engine_statements ||= self.search_statements.select do |search_statement|
32
+ search_statement.options[:engines].try(:include?, engine_sym)
33
+ end
34
+ end
35
+
36
+ def prepared_search_statements
37
+ @prepared_search_statements ||= search_engine_statements.map do |search_statement|
38
+ search_statement.pattern = args[search_statement.param_name]
39
+ search_statement.pattern.present? ? search_statement : nil
40
+ end.compact
41
+ end
42
+
43
+ # Redefine this method in subclass if your engine name does not match class
44
+ def engine_sym
45
+ @engine_sym ||= self.class.name.to_s.demodulize.underscore.to_sym
46
+ end
47
+
48
+ def rank
49
+ #Must be implemented in subclasses
50
+ nil
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,58 @@
1
+ module Mincer
2
+ module PgSearch
3
+ module SearchEngines
4
+ class Fulltext < Base
5
+ DISALLOWED_TSQUERY_CHARACTERS = /[!(:&|)'?\\]/
6
+
7
+ def conditions
8
+ return nil unless prepared_search_statements.any?
9
+ arel_group do
10
+ conditions = prepared_search_statements.map do |search_statement|
11
+ arel_group(Arel::Nodes::InfixOperation.new('@@', document_for(search_statement), query_for(search_statement)))
12
+ end
13
+ join_expressions(conditions, :or)
14
+ end
15
+ end
16
+
17
+ def rank
18
+ return nil unless prepared_search_statements.any?
19
+ arel_group do
20
+ ranks = prepared_search_statements.map do |search_statement|
21
+ Arel::Nodes::NamedFunction.new('ts_rank', [document_for(search_statement), query_for(search_statement)]).to_sql
22
+ end
23
+ join_expressions(ranks, '+')
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def prepared_search_statements
30
+ @prepared_search_statements ||= search_engine_statements.map do |search_statement|
31
+ pattern = args[search_statement.param_name]
32
+ search_statement.pattern = pattern && pattern.gsub(DISALLOWED_TSQUERY_CHARACTERS, ' ').split(' ').compact
33
+ search_statement.pattern.present? && search_statement.pattern.any? ? search_statement : nil
34
+ end.compact
35
+ end
36
+
37
+ def document_for(search_statement)
38
+ arel_group do
39
+ search_statement.columns.map do |search_column|
40
+ sanitized_term = sanitize_column(search_column, search_statement.sanitizers + [:coalesce])
41
+ Arel::Nodes::NamedFunction.new('to_tsvector', [search_statement.dictionary, sanitized_term]).to_sql
42
+ end.join(' || ')
43
+ end
44
+ end
45
+
46
+ def query_for(search_statement)
47
+ terms_delimiter = search_statement.options[:any_word] ? '|' : '&'
48
+ tsquery_sql = Arel.sql(search_statement.terms.map { |term| sanitize_string_quoted(term, search_statement.sanitizers).to_sql }.join(" || ' #{terms_delimiter} ' || "))
49
+ arel_group do
50
+ Arel::Nodes::NamedFunction.new('to_tsquery', [search_statement.dictionary, tsquery_sql])
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,41 @@
1
+ module Mincer
2
+ module PgSearch
3
+ module SearchEngines
4
+ class Trigram < Base
5
+
6
+ def conditions
7
+ return nil unless prepared_search_statements.any?
8
+ arel_group do
9
+ join_expressions(prepared_search_statements.map { |search_statement| document_for(search_statement) }, :or)
10
+ end
11
+ end
12
+
13
+ def rank
14
+ return nil unless prepared_search_statements.any?
15
+ arel_group do
16
+ join_expressions(prepared_search_statements.map { |search_statement| rank_for(search_statement) }, :+)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+
23
+ def document_for(search_statement)
24
+ documents = search_statement.columns.map do |search_column|
25
+ similarity = Arel::Nodes::NamedFunction.new('similarity', [sanitize_column(search_column, search_statement.sanitizers), sanitize_string(search_statement.pattern, search_statement.sanitizers)])
26
+ arel_group(similarity.gteq(search_statement.threshold))
27
+ end
28
+ join_expressions(documents, :or)
29
+ end
30
+
31
+ def rank_for(search_statement)
32
+ ranks = search_statement.columns.map do |search_column|
33
+ Arel::Nodes::NamedFunction.new('similarity', [sanitize_column(search_column, search_statement.sanitizers), sanitize_string(search_statement.pattern, search_statement.sanitizers)])
34
+ end
35
+ join_expressions(ranks, :+)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ module Mincer
2
+ module Processors
3
+ module PgSearch
4
+ class SearchStatement
5
+ attr_accessor :columns, :options, :pattern
6
+ alias_method :terms, :pattern
7
+
8
+ def initialize(columns, options = {})
9
+ @columns, @options = columns, ::ActiveSupport::HashWithIndifferentAccess.new(options)
10
+ end
11
+
12
+ def sanitizers
13
+ @sanitizers ||= Sanitizer::AVAILABLE_SANITIZERS.select { |sanitizer| options[sanitizer] }
14
+ end
15
+
16
+ def dictionary
17
+ options[:dictionary] || Mincer.config.pg_search.fulltext_engine[:dictionary]
18
+ end
19
+
20
+ def threshold
21
+ options[:threshold] || Mincer.config.pg_search.trigram_engine[:threshold]
22
+ end
23
+
24
+ def param_name
25
+ options[:param_name] || Mincer.config.pg_search.param_name
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,113 @@
1
+ module Mincer
2
+ module Processors
3
+ module Sorting
4
+ class Processor
5
+ def initialize(mincer)
6
+ @mincer, @args, @relation = mincer, mincer.args, mincer.relation
7
+ end
8
+
9
+ def apply
10
+ relation = @relation.order(sort_string)
11
+ @mincer.sort_attribute, @mincer.sort_order = sort_attr, order_attr
12
+ relation
13
+ end
14
+
15
+ def sort_string
16
+ if sort_attr
17
+ "#{sort_attr} #{order_attr || default_order}"
18
+ else
19
+ "#{default_sort} #{order_attr || default_order}"
20
+ end
21
+ end
22
+
23
+ def sort_attr
24
+ @mincer.send(:allowed_sort_attributes).include?(sort) && sort
25
+ end
26
+
27
+ def order_attr
28
+ %w{asc desc}.include?(order.try(:downcase)) && order
29
+ end
30
+
31
+ def sort
32
+ @args[::Mincer.config.sorting.sort_param_name]
33
+ end
34
+
35
+ def default_sort
36
+ @mincer.try(:default_sort_attribute)
37
+ end
38
+
39
+ def order
40
+ @args[::Mincer.config.sorting.order_param_name]
41
+ end
42
+
43
+ def default_order
44
+ @mincer.try(:default_sort_order)
45
+ end
46
+
47
+ end
48
+
49
+
50
+ module Options
51
+ extend ActiveSupport::Concern
52
+
53
+ included do
54
+ # Used in view helpers
55
+ attr_accessor :sort_attribute, :sort_order
56
+ end
57
+
58
+ module ClassMethods
59
+ def skip_sorting!
60
+ active_processors.delete(Mincer::Processors::Sorting::Processor)
61
+ end
62
+ end
63
+
64
+ # Default sort attribute. You must override this method if you want something else
65
+ def default_sort_attribute
66
+ ::Mincer.config.sorting.sort_attribute
67
+ end
68
+
69
+ # Default order attribute. You must override this method if you want something else
70
+ def default_sort_order
71
+ ::Mincer.config.sorting.order_attribute
72
+ end
73
+
74
+ # Allowed sort attributes, should return array of strings
75
+ def allowed_sort_attributes
76
+ @scope.attribute_names
77
+ end
78
+ end
79
+
80
+ class Configuration
81
+ include ActiveSupport::Configurable
82
+
83
+ config_accessor :sort_param_name do
84
+ :sort
85
+ end
86
+
87
+ config_accessor :sort_attribute do
88
+ :id
89
+ end
90
+
91
+ config_accessor :order_param_name do
92
+ :order
93
+ end
94
+
95
+ config_accessor :order_attribute do
96
+ :asc
97
+ end
98
+
99
+ config_accessor :asc_class do
100
+ 'sorted order_down'
101
+ end
102
+
103
+ config_accessor :desc_class do
104
+ 'sorted order_up'
105
+ end
106
+
107
+ end
108
+
109
+ end
110
+ end
111
+ end
112
+
113
+ ::Mincer.add_processor(:sorting)
@@ -1,7 +1,7 @@
1
1
  module Mincer
2
2
 
3
3
  def self.version
4
- Gem::Version.new '0.1.2'
4
+ Gem::Version.new '0.2.0'
5
5
  end
6
6
 
7
7
  module VERSION #:nodoc:
data/lib/mincer.rb CHANGED
@@ -1,6 +1,7 @@
1
+ require 'ostruct'
1
2
  require 'mincer/version'
2
-
3
-
3
+ require 'mincer/core_ext/string'
4
+ require 'mincer/config'
4
5
  require 'mincer/base'
5
6
 
6
7
  module Mincer
@@ -15,24 +16,39 @@ module Mincer
15
16
  def self.connection
16
17
  ::ActiveRecord::Base.connection()
17
18
  end
18
- end
19
19
 
20
+ def self.add_processor(processor)
21
+ processor_scope = ::Mincer::Processors.const_get(ActiveSupport::Inflector.camelize(processor.to_s, true))
22
+ ::Mincer.processors << processor_scope.const_get('Processor')
23
+ ::Mincer::Base.send(:include, processor_scope.const_get('Options')) if processor_scope.const_defined?('Options')
24
+ ::Mincer.config.add(processor, processor_scope.const_get('Configuration')) if processor_scope.const_defined?('Configuration') if processor_scope.const_defined?('Configuration')
25
+ end
20
26
 
21
- # Loading processors
22
- require 'mincer/processors/sort'
23
- require 'mincer/processors/paginate'
24
- require 'mincer/processors/search'
25
- require 'mincer/processors/cache_digest'
26
- require 'mincer/processors/pg_json_dumper'
27
- ::Mincer::Processors.constants.each do |k|
28
- klass = ::Mincer::Processors.const_get(k)
29
- if klass.is_a?(Class)
30
- ::Mincer.processors << klass
31
- elsif klass.is_a?(Module)
32
- ::Mincer::Base.send(:include, klass)
27
+ def self.pg_extension_installed?(extension)
28
+ @installed_extensions ||= {}
29
+ if @installed_extensions[extension.to_sym].nil?
30
+ @installed_extensions[extension.to_sym] = ::Mincer.connection.execute("SELECT DISTINCT p.proname FROM pg_proc p WHERE p.proname = '#{extension}'").count > 0
31
+ end
32
+ @installed_extensions[extension.to_sym]
33
33
  end
34
+
34
35
  end
35
36
 
37
+ # Loading helpers
38
+ require 'mincer/processors/helpers'
39
+
40
+ # Loading processors
41
+ require 'mincer/processors/sorting/processor'
42
+ require 'mincer/processors/pagination/processor'
43
+ require 'mincer/processors/pg_search/search_statement'
44
+ require 'mincer/processors/pg_search/sanitizer'
45
+ require 'mincer/processors/pg_search/search_engines/base'
46
+ require 'mincer/processors/pg_search/search_engines/array'
47
+ require 'mincer/processors/pg_search/search_engines/fulltext'
48
+ require 'mincer/processors/pg_search/search_engines/trigram'
49
+ require 'mincer/processors/pg_search/processor'
50
+ require 'mincer/processors/cache_digest/processor'
51
+ require 'mincer/processors/pg_json_dumper/processor'
36
52
 
37
53
  # Loading ActionView helpers
38
54
  if defined?(ActionView)
@@ -42,19 +58,3 @@ if defined?(ActionView)
42
58
  ActionView::Base.send(:include, klass) if klass.is_a?(Module)
43
59
  end
44
60
  end
45
-
46
-
47
- #if defined?(::Rails)
48
- # module Mincer
49
- # class Railtie < ::Rails::Railtie
50
- # initializer 'mincer.setup_paths' do
51
- # end
52
- #
53
- # initializer 'carrierwave.active_record' do
54
- # #ActiveSupport.on_load :active_record do
55
- # # require 'carrierwave/orm/activerecord'
56
- # #end
57
- # end
58
- # end
59
- # end
60
- #end
data/mincer.gemspec CHANGED
@@ -22,10 +22,8 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_development_dependency 'bundler', '~> 1.3'
24
24
  spec.add_development_dependency 'rake'
25
- spec.add_development_dependency 'rspec', '~> 2.14.1'
26
25
  spec.add_development_dependency 'pg'
27
26
  spec.add_development_dependency 'sqlite3'
28
27
  spec.add_development_dependency 'kaminari'
29
28
  spec.add_development_dependency 'will_paginate'
30
- spec.add_development_dependency 'textacular'
31
29
  end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mincer::ActionView::SortHelper do
4
+ describe 'sort_url_for' do
5
+ it 'does something' do
6
+ pending 'Wait for rails integration testing'
7
+ #helper.url_for
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe ::Mincer::Base do
5
+
6
+ it 'passes all missing methods to relation' do
7
+ setup_basic_sqlite3_table
8
+ subject = Class.new(Mincer::Base) do
9
+ pg_search [{ columns: %w{"active_record_models"."tags" }, engines: [:array] }]
10
+ end
11
+ query = subject.new(ActiveRecordModel)
12
+ expect { query.attribute_names }.not_to raise_exception
13
+ end
14
+
15
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe ::Mincer::Configuration do
5
+
6
+
7
+ end