ransack 1.8.4 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/SECURITY.md +12 -0
  4. data/.github/workflows/cronjob.yml +102 -0
  5. data/.github/workflows/deploy.yml +35 -0
  6. data/.github/workflows/rubocop.yml +20 -0
  7. data/.github/workflows/test-deploy.yml +29 -0
  8. data/.github/workflows/test.yml +130 -0
  9. data/.gitignore +3 -0
  10. data/{lib/ransack/adapters/mongoid/3.2/.gitkeep → .nojekyll} +0 -0
  11. data/.rubocop.yml +44 -0
  12. data/CHANGELOG.md +352 -0
  13. data/CONTRIBUTING.md +25 -13
  14. data/Gemfile +26 -27
  15. data/README.md +65 -815
  16. data/Rakefile +1 -22
  17. data/bug_report_templates/test-ransack-scope-and-column-same-name.rb +78 -0
  18. data/bug_report_templates/test-ransacker-arel-present-predicate.rb +71 -0
  19. data/docs/.gitignore +19 -0
  20. data/docs/.nojekyll +0 -0
  21. data/docs/babel.config.js +3 -0
  22. data/docs/blog/2022-03-27-ransack-3.0.0.md +20 -0
  23. data/docs/docs/getting-started/_category_.json +4 -0
  24. data/docs/docs/getting-started/advanced-mode.md +46 -0
  25. data/docs/docs/getting-started/configuration.md +47 -0
  26. data/docs/docs/getting-started/search-matches.md +67 -0
  27. data/docs/docs/getting-started/simple-mode.md +284 -0
  28. data/docs/docs/getting-started/sorting.md +79 -0
  29. data/docs/docs/getting-started/using-predicates.md +282 -0
  30. data/docs/docs/going-further/_category_.json +4 -0
  31. data/docs/docs/going-further/acts-as-taggable-on.md +114 -0
  32. data/docs/docs/going-further/associations.md +70 -0
  33. data/docs/docs/going-further/custom-predicates.md +52 -0
  34. data/docs/docs/going-further/documentation.md +43 -0
  35. data/docs/docs/going-further/exporting-to-csv.md +49 -0
  36. data/docs/docs/going-further/external-guides.md +57 -0
  37. data/docs/docs/going-further/form-customisation.md +63 -0
  38. data/docs/docs/going-further/i18n.md +53 -0
  39. data/docs/docs/going-further/img/create_release.png +0 -0
  40. data/docs/docs/going-further/merging-searches.md +41 -0
  41. data/docs/docs/going-further/other-notes.md +428 -0
  42. data/docs/docs/going-further/polymorphic-search.md +40 -0
  43. data/docs/docs/going-further/ransackers.md +331 -0
  44. data/docs/docs/going-further/release_process.md +36 -0
  45. data/docs/docs/going-further/saving-queries.md +82 -0
  46. data/docs/docs/going-further/searching-postgres.md +57 -0
  47. data/docs/docs/going-further/wiki-contributors.md +82 -0
  48. data/docs/docs/intro.md +99 -0
  49. data/docs/docusaurus.config.js +120 -0
  50. data/docs/package.json +38 -0
  51. data/docs/sidebars.js +31 -0
  52. data/docs/src/components/HomepageFeatures/index.js +64 -0
  53. data/docs/src/components/HomepageFeatures/styles.module.css +11 -0
  54. data/docs/src/css/custom.css +39 -0
  55. data/docs/src/pages/index.module.css +23 -0
  56. data/docs/src/pages/markdown-page.md +7 -0
  57. data/docs/static/.nojekyll +0 -0
  58. data/docs/static/img/docusaurus.png +0 -0
  59. data/docs/static/img/favicon.ico +0 -0
  60. data/docs/static/img/logo.svg +1 -0
  61. data/docs/static/img/tutorial/docsVersionDropdown.png +0 -0
  62. data/docs/static/img/tutorial/localeDropdown.png +0 -0
  63. data/docs/static/img/undraw_docusaurus_mountain.svg +171 -0
  64. data/docs/static/img/undraw_docusaurus_react.svg +170 -0
  65. data/docs/static/img/undraw_docusaurus_tree.svg +40 -0
  66. data/docs/static/logo/ransack-h.png +0 -0
  67. data/docs/static/logo/ransack-h.svg +34 -0
  68. data/docs/static/logo/ransack-v.png +0 -0
  69. data/docs/static/logo/ransack-v.svg +34 -0
  70. data/docs/static/logo/ransack.png +0 -0
  71. data/docs/static/logo/ransack.svg +21 -0
  72. data/docs/yarn.lock +8436 -0
  73. data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +70 -0
  74. data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +92 -0
  75. data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +11 -0
  76. data/lib/polyamorous/activerecord_7.0_ruby_2/join_association.rb +1 -0
  77. data/lib/polyamorous/activerecord_7.0_ruby_2/join_dependency.rb +1 -0
  78. data/lib/polyamorous/activerecord_7.0_ruby_2/reflection.rb +1 -0
  79. data/lib/polyamorous/activerecord_7.1_ruby_2/join_association.rb +1 -0
  80. data/lib/polyamorous/activerecord_7.1_ruby_2/join_dependency.rb +1 -0
  81. data/lib/polyamorous/activerecord_7.1_ruby_2/reflection.rb +1 -0
  82. data/lib/polyamorous/join.rb +70 -0
  83. data/lib/polyamorous/polyamorous.rb +24 -0
  84. data/lib/polyamorous/swapping_reflection_class.rb +11 -0
  85. data/lib/polyamorous/tree_node.rb +7 -0
  86. data/lib/polyamorous.rb +1 -0
  87. data/lib/ransack/adapters/active_record/base.rb +14 -3
  88. data/lib/ransack/adapters/active_record/context.rb +140 -196
  89. data/lib/ransack/adapters/active_record/ransack/constants.rb +19 -4
  90. data/lib/ransack/adapters/active_record/ransack/context.rb +9 -19
  91. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +7 -7
  92. data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -5
  93. data/lib/ransack/adapters/active_record/ransack/visitor.rb +23 -0
  94. data/lib/ransack/adapters/active_record.rb +0 -9
  95. data/lib/ransack/adapters.rb +2 -0
  96. data/lib/ransack/configuration.rb +52 -2
  97. data/lib/ransack/constants.rb +1 -5
  98. data/lib/ransack/context.rb +29 -24
  99. data/lib/ransack/helpers/form_builder.rb +12 -6
  100. data/lib/ransack/helpers/form_helper.rb +11 -3
  101. data/lib/ransack/helpers.rb +1 -1
  102. data/lib/ransack/locale/ar.yml +70 -0
  103. data/lib/ransack/locale/az.yml +70 -0
  104. data/lib/ransack/locale/bg.yml +70 -0
  105. data/lib/ransack/locale/ca.yml +70 -0
  106. data/lib/ransack/locale/el.yml +70 -0
  107. data/lib/ransack/locale/es.yml +22 -22
  108. data/lib/ransack/locale/fa.yml +70 -0
  109. data/lib/ransack/locale/fi.yml +71 -0
  110. data/lib/ransack/locale/nl.yml +4 -4
  111. data/lib/ransack/locale/ru.yml +70 -0
  112. data/lib/ransack/locale/sk.yml +70 -0
  113. data/lib/ransack/locale/sv.yml +70 -0
  114. data/lib/ransack/locale/tr.yml +70 -0
  115. data/lib/ransack/locale/zh-CN.yml +12 -12
  116. data/lib/ransack/nodes/attribute.rb +2 -2
  117. data/lib/ransack/nodes/condition.rb +7 -1
  118. data/lib/ransack/nodes/grouping.rb +3 -8
  119. data/lib/ransack/nodes/sort.rb +3 -3
  120. data/lib/ransack/nodes/value.rb +3 -3
  121. data/lib/ransack/predicate.rb +13 -20
  122. data/lib/ransack/search.rb +7 -4
  123. data/lib/ransack/translate.rb +115 -115
  124. data/lib/ransack/version.rb +1 -1
  125. data/lib/ransack/visitor.rb +1 -12
  126. data/lib/ransack.rb +7 -5
  127. data/ransack.gemspec +9 -25
  128. data/spec/blueprints/articles.rb +1 -1
  129. data/spec/blueprints/comments.rb +1 -1
  130. data/spec/blueprints/notes.rb +1 -1
  131. data/spec/blueprints/tags.rb +1 -1
  132. data/spec/console.rb +5 -5
  133. data/spec/helpers/polyamorous_helper.rb +13 -0
  134. data/spec/helpers/ransack_helper.rb +1 -1
  135. data/spec/polyamorous/activerecord_compatibility_spec.rb +15 -0
  136. data/spec/polyamorous/join_association_spec.rb +30 -0
  137. data/spec/polyamorous/join_dependency_spec.rb +81 -0
  138. data/spec/polyamorous/join_spec.rb +19 -0
  139. data/spec/ransack/adapters/active_record/base_spec.rb +105 -11
  140. data/spec/ransack/adapters/active_record/context_spec.rb +63 -24
  141. data/spec/ransack/configuration_spec.rb +24 -0
  142. data/spec/ransack/helpers/form_builder_spec.rb +3 -15
  143. data/spec/ransack/helpers/form_helper_spec.rb +135 -168
  144. data/spec/ransack/nodes/condition_spec.rb +13 -0
  145. data/spec/ransack/nodes/grouping_spec.rb +2 -2
  146. data/spec/ransack/nodes/value_spec.rb +115 -0
  147. data/spec/ransack/predicate_spec.rb +54 -2
  148. data/spec/ransack/search_spec.rb +266 -36
  149. data/spec/spec_helper.rb +14 -5
  150. data/spec/support/schema.rb +99 -21
  151. metadata +117 -187
  152. data/.travis.yml +0 -86
  153. data/lib/ransack/adapters/active_record/3.0/compat.rb +0 -179
  154. data/lib/ransack/adapters/active_record/3.0/context.rb +0 -203
  155. data/lib/ransack/adapters/active_record/3.1/context.rb +0 -212
  156. data/lib/ransack/adapters/active_record/3.2/context.rb +0 -44
  157. data/lib/ransack/adapters/active_record/compat.rb +0 -14
  158. data/lib/ransack/adapters/mongoid/attributes/attribute.rb +0 -37
  159. data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +0 -17
  160. data/lib/ransack/adapters/mongoid/attributes/predications.rb +0 -141
  161. data/lib/ransack/adapters/mongoid/base.rb +0 -134
  162. data/lib/ransack/adapters/mongoid/context.rb +0 -212
  163. data/lib/ransack/adapters/mongoid/inquiry_hash.rb +0 -23
  164. data/lib/ransack/adapters/mongoid/ransack/constants.rb +0 -88
  165. data/lib/ransack/adapters/mongoid/ransack/context.rb +0 -60
  166. data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +0 -27
  167. data/lib/ransack/adapters/mongoid/ransack/translate.rb +0 -13
  168. data/lib/ransack/adapters/mongoid/ransack/visitor.rb +0 -24
  169. data/lib/ransack/adapters/mongoid/table.rb +0 -35
  170. data/lib/ransack/adapters/mongoid.rb +0 -15
  171. data/spec/mongoid/adapters/mongoid/base_spec.rb +0 -314
  172. data/spec/mongoid/adapters/mongoid/context_spec.rb +0 -56
  173. data/spec/mongoid/configuration_spec.rb +0 -162
  174. data/spec/mongoid/dependencies_spec.rb +0 -8
  175. data/spec/mongoid/helpers/ransack_helper.rb +0 -11
  176. data/spec/mongoid/nodes/condition_spec.rb +0 -49
  177. data/spec/mongoid/nodes/grouping_spec.rb +0 -13
  178. data/spec/mongoid/predicate_spec.rb +0 -155
  179. data/spec/mongoid/search_spec.rb +0 -445
  180. data/spec/mongoid/support/mongoid.yml +0 -11
  181. data/spec/mongoid/support/schema.rb +0 -135
  182. data/spec/mongoid/translate_spec.rb +0 -14
  183. data/spec/mongoid_spec_helper.rb +0 -63
  184. data/spec/ransack/dependencies_spec.rb +0 -12
@@ -1,88 +0,0 @@
1
- module Ransack
2
- module Constants
3
- DERIVED_PREDICATES = [
4
- [CONT, {
5
- :arel_predicate => 'matches',
6
- :formatter => proc { |v| "#{escape_regex(v)}" }
7
- }
8
- ],
9
- ['not_cont', {
10
- :arel_predicate => 'does_not_match',
11
- :formatter => proc { |v| "#{escape_regex(v)}" }
12
- }
13
- ],
14
- ['start', {
15
- :arel_predicate => 'matches',
16
- :formatter => proc { |v| "\\A#{escape_regex(v)}" }
17
- }
18
- ],
19
- ['not_start', {
20
- :arel_predicate => 'does_not_match',
21
- :formatter => proc { |v| "\\A#{escape_regex(v)}" }
22
- }
23
- ],
24
- ['end', {
25
- :arel_predicate => 'matches',
26
- :formatter => proc { |v| "#{escape_regex(v)}\\Z" }
27
- }
28
- ],
29
- ['not_end', {
30
- :arel_predicate => 'does_not_match',
31
- :formatter => proc { |v| "#{escape_regex(v)}\\Z" }
32
- }
33
- ],
34
- ['true', {
35
- :arel_predicate => 'eq',
36
- :compounds => false,
37
- :type => :boolean,
38
- :validator => proc { |v| TRUE_VALUES.include?(v) }
39
- }
40
- ],
41
- ['false', {
42
- :arel_predicate => 'eq',
43
- :compounds => false,
44
- :type => :boolean,
45
- :validator => proc { |v| TRUE_VALUES.include?(v) },
46
- :formatter => proc { |v| !v }
47
- }
48
- ],
49
- ['present', {
50
- :arel_predicate => proc { |v| v ? 'not_eq_all' : 'eq_any' },
51
- :compounds => false,
52
- :type => :boolean,
53
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
54
- :formatter => proc { |v| [nil, ''] }
55
- }
56
- ],
57
- ['blank', {
58
- :arel_predicate => proc { |v| v ? 'eq_any' : 'not_eq_all' },
59
- :compounds => false,
60
- :type => :boolean,
61
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
62
- :formatter => proc { |v| [nil, ''] }
63
- }
64
- ],
65
- ['null', {
66
- :arel_predicate => proc { |v| v ? 'eq' : 'not_eq' },
67
- :compounds => false,
68
- :type => :boolean,
69
- :validator => proc { |v| BOOLEAN_VALUES.include?(v)},
70
- :formatter => proc { |v| nil }
71
- }
72
- ],
73
- ['not_null', {
74
- :arel_predicate => proc { |v| v ? 'not_eq' : 'eq' },
75
- :compounds => false,
76
- :type => :boolean,
77
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
78
- :formatter => proc { |v| nil } }
79
- ]
80
- ]
81
-
82
- module_function
83
- # does nothing
84
- def escape_regex(unescaped)
85
- Regexp.escape(unescaped)
86
- end
87
- end
88
- end
@@ -1,60 +0,0 @@
1
- require 'ransack/visitor'
2
-
3
- module Ransack
4
- class Context
5
- # attr_reader :arel_visitor
6
-
7
- class << self
8
-
9
- def for_class(klass, options = {})
10
- if klass.ancestors.include?(::Mongoid::Document)
11
- Adapters::Mongoid::Context.new(klass, options)
12
- end
13
- end
14
-
15
- def for_object(object, options = {})
16
- case object
17
- when ActiveRecord::Relation
18
- Adapters::ActiveRecord::Context.new(object.klass, options)
19
- end
20
- end
21
-
22
- end # << self
23
-
24
- def initialize(object, options = {})
25
- @object = relation_for(object)
26
- @klass = @object.klass
27
- # @join_dependency = join_dependency(@object)
28
- # @join_type = options[:join_type] || Arel::OuterJoin
29
- @search_key = options[:search_key] || Ransack.options[:search_key]
30
-
31
- @base = @object.klass
32
- # @engine = @base.arel_engine
33
-
34
- # @default_table = Arel::Table.new(
35
- # @base.table_name, :as => @base.aliased_table_name, :engine => @engine
36
- # )
37
- @bind_pairs = Hash.new do |hash, key|
38
- parent, attr_name = get_parent_and_attribute_name(key.to_s)
39
- if parent && attr_name
40
- hash[key] = [parent, attr_name]
41
- end
42
- end
43
- end
44
-
45
- def klassify(obj)
46
- if Class === obj && ::ActiveRecord::Base > obj
47
- obj
48
- elsif obj.respond_to? :klass
49
- obj.klass
50
- elsif obj.respond_to? :active_record # Rails 3
51
- obj.active_record
52
- elsif obj.respond_to? :base_klass # Rails 4
53
- obj.base_klass
54
- else
55
- raise ArgumentError, "Don't know how to klassify #{obj.inspect}"
56
- end
57
- end
58
-
59
- end
60
- end
@@ -1,27 +0,0 @@
1
- module Ransack
2
- module Nodes
3
- class Condition
4
-
5
- def arel_predicate
6
- predicates = attributes.map do |attr|
7
- attr.attr.send(
8
- arel_predicate_for_attribute(attr),
9
- formatted_values_for_attribute(attr)
10
- )
11
- end
12
-
13
- if predicates.size > 1
14
- case combinator
15
- when 'and'
16
- Arel::Nodes::Grouping.new(Arel::Nodes::And.new(predicates))
17
- when 'or'
18
- predicates.inject(&:or)
19
- end
20
- else
21
- predicates.first
22
- end
23
- end
24
-
25
- end # Condition
26
- end
27
- end
@@ -1,13 +0,0 @@
1
- module Ransack
2
- module Translate
3
-
4
- def self.i18n_key(klass)
5
- # if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0
6
- # klass.model_name.i18n_key.to_s.tr('.', '/')
7
- # else
8
- # klass.model_name.i18n_key.to_s
9
- # end
10
- klass.model_name.i18n_key.to_s
11
- end
12
- end
13
- end
@@ -1,24 +0,0 @@
1
- module Ransack
2
- class Visitor
3
- def visit_and(object)
4
- nodes = object.values.map { |o| accept(o) }.compact
5
- return nil unless nodes.size > 0
6
-
7
- if nodes.size > 1
8
- nodes.inject(&:and)
9
- else
10
- nodes.first
11
- end
12
- end
13
-
14
- def quoted?(object)
15
- case object
16
- when Arel::Nodes::SqlLiteral, Bignum, Fixnum
17
- false
18
- else
19
- true
20
- end
21
- end
22
-
23
- end
24
- end
@@ -1,35 +0,0 @@
1
- module Ransack
2
- module Adapters
3
- module Mongoid
4
- class Table
5
- attr_accessor :name
6
-
7
- alias :table_name :name
8
-
9
- def initialize(object, engine = nil)
10
- @object = object
11
- @name = object.collection.name
12
- @engine = engine
13
- @columns = nil
14
- @aliases = []
15
- @table_alias = nil
16
- @primary_key = nil
17
-
18
- if Hash === engine
19
- # @engine = engine[:engine] || Table.engine
20
-
21
- # Sometime AR sends an :as parameter to table, to let the table know
22
- # that it is an Alias. We may want to override new, and return a
23
- # TableAlias node?
24
- # @table_alias = engine[:as] unless engine[:as].to_s == @name
25
- end
26
- end
27
-
28
- def [](name)
29
- Ransack::Adapters::Mongoid::Attribute.new self, name
30
- end
31
-
32
- end
33
- end
34
- end
35
- end
@@ -1,15 +0,0 @@
1
- require 'ransack/adapters/mongoid/base'
2
- ::Mongoid::Document.send :include, Ransack::Adapters::Mongoid::Base
3
-
4
- require 'ransack/adapters/mongoid/attributes/attribute'
5
- require 'ransack/adapters/mongoid/table'
6
- require 'ransack/adapters/mongoid/inquiry_hash'
7
-
8
- case ::Mongoid::VERSION
9
- when /^3\.2\./
10
- require 'ransack/adapters/mongoid/3.2/context'
11
- else
12
- require 'ransack/adapters/mongoid/context'
13
- end
14
-
15
- Ransack::SUPPORTS_ATTRIBUTE_ALIAS = false
@@ -1,314 +0,0 @@
1
- require 'mongoid_spec_helper'
2
-
3
- module Ransack
4
- module Adapters
5
- module Mongoid
6
- describe Base do
7
-
8
- subject { Person }
9
-
10
- it { should respond_to :ransack }
11
- it { should respond_to :search }
12
-
13
- describe '#search' do
14
- subject { Person.search }
15
-
16
- it { should be_a Search }
17
- it 'has a Mongoid::Criteria as its object' do
18
- expect(subject.object).to be_an ::Mongoid::Criteria
19
- end
20
-
21
- context 'with scopes' do
22
- before do
23
- allow(Person)
24
- .to receive(:ransackable_scopes)
25
- .and_return([:active, :over_age])
26
- end
27
-
28
- it "applies true scopes" do
29
- search = Person.search('active' => true)
30
- expect(search.result.selector).to eq({ 'active' => 1 })
31
- end
32
-
33
- it "ignores unlisted scopes" do
34
- search = Person.search('restricted' => true)
35
- expect(search.result.selector).to_not eq({ 'restricted' => 1})
36
- end
37
-
38
- it "ignores false scopes" do
39
- search = Person.search('active' => false)
40
- expect(search.result.selector).to_not eq({ 'active' => 1 })
41
- end
42
-
43
- it "passes values to scopes" do
44
- search = Person.search('over_age' => 18)
45
- expect(search.result.selector).to eq({ 'age' => { '$gt' => 18 } })
46
- end
47
-
48
- it "chains scopes" do
49
- search = Person.search('over_age' => 18, 'active' => true)
50
- expect(search.result.selector).to eq({ 'age' => { '$gt' => 18 }, 'active' => 1 })
51
- end
52
- end
53
- end
54
-
55
- describe '#ransack_alias' do
56
- it 'translates an alias to the correct attributes' do
57
- p = Person.create!(name: 'Meatloaf', email: 'babies@example.com')
58
-
59
- s = Person.ransack(term_cont: 'atlo')
60
- expect(s.result.to_a).to eq [p]
61
-
62
- s = Person.ransack(term_cont: 'babi')
63
- expect(s.result.to_a).to eq [p]
64
-
65
- s = Person.ransack(term_cont: 'nomatch')
66
- expect(s.result.to_a).to eq []
67
- end
68
-
69
- it 'makes aliases available to subclasses' do
70
- yngwie = Musician.create!(name: 'Yngwie Malmsteen')
71
-
72
- musicians = Musician.ransack(term_cont: 'ngw').result
73
- expect(musicians).to eq([yngwie])
74
- end
75
-
76
- it 'handles naming collisions gracefully' do
77
- frank = Person.create!(name: 'Frank Stallone')
78
-
79
- people = Person.ransack(term_cont: 'allon').result
80
- expect(people).to eq([frank])
81
-
82
- Class.new(Article) do
83
- ransack_alias :term, :title
84
- end
85
-
86
- people = Person.ransack(term_cont: 'allon').result
87
- expect(people).to eq([frank])
88
- end
89
- end
90
-
91
- describe '#ransacker' do
92
- # For infix tests
93
- def self.sane_adapter?
94
- case ::Mongoid::Document.connection.adapter_name
95
- when "SQLite3", "PostgreSQL"
96
- true
97
- else
98
- false
99
- end
100
- end
101
- # # in schema.rb, class Person:
102
- # ransacker :reversed_name, formatter: proc { |v| v.reverse } do |parent|
103
- # parent.table[:name]
104
- # end
105
-
106
- # ransacker :doubled_name do |parent|
107
- # Arel::Nodes::InfixOperation.new(
108
- # '||', parent.table[:name], parent.table[:name]
109
- # )
110
- # end
111
-
112
- it 'creates ransack attributes' do
113
- s = Person.search(:reversed_name_eq => 'htimS cirA')
114
- expect(s.result.size).to eq(Person.where(name: 'Aric Smith').count)
115
-
116
- expect(s.result.first).to eq Person.where(name: 'Aric Smith').first
117
- end
118
-
119
- context 'with joins' do
120
- before { pending 'not implemented for mongoid' }
121
-
122
- it 'can be accessed through associations' do
123
- s = Person.search(:children_reversed_name_eq => 'htimS cirA')
124
- expect(s.result.to_sql).to match(
125
- /#{quote_table_name("children_people")}.#{
126
- quote_column_name("name")} = 'Aric Smith'/
127
- )
128
- end
129
-
130
- it "should keep proper key value pairs in the params hash" do
131
- s = Person.search(:children_reversed_name_eq => 'Testing')
132
- expect(s.result.to_sql).to match /LEFT OUTER JOIN/
133
- end
134
-
135
- end
136
-
137
- it 'allows an "attribute" to be an InfixOperation' do
138
- s = Person.search(:doubled_name_eq => 'Aric SmithAric Smith')
139
- expect(s.result.first).to eq Person.where(name: 'Aric Smith').first
140
- end if defined?(Arel::Nodes::InfixOperation) && sane_adapter?
141
-
142
- it "doesn't break #count if using InfixOperations" do
143
- s = Person.search(:doubled_name_eq => 'Aric SmithAric Smith')
144
- expect(s.result.count).to eq 1
145
- end if defined?(Arel::Nodes::InfixOperation) && sane_adapter?
146
-
147
- it "should remove empty key value pairs from the params hash" do
148
- s = Person.search(:reversed_name_eq => '')
149
- expect(s.result.selector).to eq({})
150
- end
151
-
152
- it "should function correctly when nil is passed in" do
153
- s = Person.search(nil)
154
- end
155
-
156
- it "should function correctly when a blank string is passed in" do
157
- s = Person.search('')
158
- end
159
-
160
- it "should function correctly when using fields with dots in them" do
161
- s = Person.search(:email_cont => "example.com")
162
- expect(s.result.exists?).to be true
163
-
164
- s = Person.search(:email_cont => "example.co.")
165
- expect(s.result.exists?).not_to be true
166
- end
167
-
168
- it "should function correctly when using fields with % in them" do
169
- Person.create!(:name => "110%-er")
170
- s = Person.search(:name_cont => "10%")
171
- expect(s.result.exists?).to be true
172
- end
173
-
174
- it "should function correctly when using fields with backslashes in them" do
175
- Person.create!(:name => "\\WINNER\\")
176
- s = Person.search(:name_cont => "\\WINNER\\")
177
- expect(s.result.exists?).to be true
178
- end
179
-
180
- it 'allows sort by "only_sort" field' do
181
- pending "it doesn't work :("
182
- s = Person.search(
183
- "s" => { "0" => { "dir" => "desc", "name" => "only_sort" } }
184
- )
185
- expect(s.result.to_sql).to match(
186
- /ORDER BY #{quote_table_name("people")}.#{
187
- quote_column_name("only_sort")} ASC/
188
- )
189
- end
190
-
191
- it "doesn't sort by 'only_search' field" do
192
- pending "it doesn't work :("
193
- s = Person.search(
194
- "s" => { "0" => { "dir" => "asc", "name" => "only_search" } }
195
- )
196
- expect(s.result.to_sql).not_to match(
197
- /ORDER BY #{quote_table_name("people")}.#{
198
- quote_column_name("only_search")} ASC/
199
- )
200
- end
201
-
202
- it 'allows search by "only_search" field' do
203
- s = Person.search(:only_search_eq => 'htimS cirA')
204
- expect(s.result.selector).to eq({'only_search' => 'htimS cirA'})
205
- end
206
-
207
- it "can't be searched by 'only_sort'" do
208
- s = Person.search(:only_sort_eq => 'htimS cirA')
209
- expect(s.result.selector).not_to eq({'only_sort' => 'htimS cirA'})
210
- end
211
-
212
- it 'allows sort by "only_admin" field, if auth_object: :admin' do
213
- s = Person.search(
214
- { "s" => { "0" => { "dir" => "asc", "name" => "only_admin" } } },
215
- { auth_object: :admin }
216
- )
217
- expect(s.result.options).to eq({ sort: { '_id' => -1, 'only_admin' => 1 } })
218
- end
219
-
220
- it "doesn't sort by 'only_admin' field, if auth_object: nil" do
221
- s = Person.search(
222
- "s" => { "0" => { "dir" => "asc", "name" => "only_admin" } }
223
- )
224
- expect(s.result.options).to eq({ sort: {'_id' => -1}})
225
- end
226
-
227
- it 'allows search by "only_admin" field, if auth_object: :admin' do
228
- s = Person.search(
229
- { :only_admin_eq => 'htimS cirA' },
230
- { :auth_object => :admin }
231
- )
232
- expect(s.result.selector).to eq({ 'only_admin' => 'htimS cirA' })
233
- end
234
-
235
- it "can't be searched by 'only_admin', if auth_object: nil" do
236
- s = Person.search(:only_admin_eq => 'htimS cirA')
237
- expect(s.result.selector).to eq({})
238
- end
239
-
240
- it 'searches by id' do
241
- ids = ['some_bson_id', 'another_bson_id']
242
- s = Person.search(:id_in => ids)
243
- expect(s.result.selector).to eq({ '_id' => { '$in' => ids } })
244
- end
245
- end
246
-
247
- describe '#ransackable_attributes' do
248
- context 'when auth_object is nil' do
249
- subject { Person.ransackable_attributes }
250
-
251
- it { should include 'name' }
252
- it { should include 'reversed_name' }
253
- it { should include 'doubled_name' }
254
- it { should include 'term' }
255
- it { should include 'only_search' }
256
- it { should_not include 'only_sort' }
257
- it { should_not include 'only_admin' }
258
- end
259
-
260
- context 'with auth_object :admin' do
261
- subject { Person.ransackable_attributes(:admin) }
262
-
263
- it { should include 'name' }
264
- it { should include 'reversed_name' }
265
- it { should include 'doubled_name' }
266
- it { should include 'term' }
267
- it { should include 'only_search' }
268
- it { should_not include 'only_sort' }
269
- it { should include 'only_admin' }
270
- end
271
- end
272
-
273
- describe '#ransortable_attributes' do
274
- context 'when auth_object is nil' do
275
- subject { Person.ransortable_attributes }
276
-
277
- it { should include 'name' }
278
- it { should include 'reversed_name' }
279
- it { should include 'doubled_name' }
280
- it { should include 'only_sort' }
281
- it { should_not include 'only_search' }
282
- it { should_not include 'only_admin' }
283
- end
284
-
285
- context 'with auth_object :admin' do
286
- subject { Person.ransortable_attributes(:admin) }
287
-
288
- it { should include 'name' }
289
- it { should include 'reversed_name' }
290
- it { should include 'doubled_name' }
291
- it { should include 'only_sort' }
292
- it { should_not include 'only_search' }
293
- it { should include 'only_admin' }
294
- end
295
- end
296
-
297
- describe '#ransackable_associations' do
298
- subject { Person.ransackable_associations }
299
-
300
- it { should include 'parent' }
301
- it { should include 'children' }
302
- it { should include 'articles' }
303
- end
304
-
305
- describe '#ransackable_scopes' do
306
- subject { Person.ransackable_scopes }
307
-
308
- it { should eq [] }
309
- end
310
-
311
- end
312
- end
313
- end
314
- end
@@ -1,56 +0,0 @@
1
- require 'mongoid_spec_helper'
2
-
3
- module Ransack
4
- module Adapters
5
- module Mongoid
6
- describe Context do
7
- subject { Context.new(Person) }
8
-
9
- describe '#relation_for' do
10
- before { pending "not implemented for mongoid" }
11
- it 'returns relation for given object' do
12
- expect(subject.object).to be_an ::ActiveRecord::Relation
13
- end
14
- end
15
-
16
- describe '#evaluate' do
17
- it 'evaluates search objects' do
18
- search = Search.new(Person, :name_eq => 'Joe Blow')
19
- result = subject.evaluate(search)
20
-
21
- expect(result).to be_an ::Mongoid::Criteria
22
- expect(result.selector).to eq({ 'name' => 'Joe Blow' })
23
- end
24
-
25
- it 'SELECTs DISTINCT when distinct: true' do
26
- pending "distinct doesn't work"
27
-
28
- search = Search.new(Person, :name_eq => 'Joe Blow')
29
- result = subject.evaluate(search, :distinct => true)
30
-
31
- expect(result).to be_an ::ActiveRecord::Relation
32
- expect(result.to_sql).to match /SELECT DISTINCT/
33
- end
34
- end
35
-
36
- it 'contextualizes strings to attributes' do
37
- attribute = subject.contextualize 'name'
38
- expect(attribute).to be_a ::Ransack::Adapters::Mongoid::Attributes::Attribute
39
- expect(attribute.name.to_s).to eq 'name'
40
- # expect(attribute.relation.table_alias).to eq 'parents_people'
41
- end
42
-
43
- it 'builds new associations if not yet built' do
44
- pending "not implemented for mongoid"
45
-
46
- attribute = subject.contextualize 'children_articles_title'
47
- expect(attribute).to be_a Arel::Attributes::Attribute
48
- expect(attribute.name.to_s).to eq 'title'
49
- expect(attribute.relation.name).to eq 'articles'
50
- expect(attribute.relation.table_alias).to be_nil
51
- end
52
-
53
- end
54
- end
55
- end
56
- end