ransack 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +12 -4
  3. data/CONTRIBUTING.md +10 -4
  4. data/Gemfile +12 -9
  5. data/README.md +46 -11
  6. data/lib/ransack.rb +4 -2
  7. data/lib/ransack/adapters/active_record.rb +1 -1
  8. data/lib/ransack/adapters/active_record/3.0/compat.rb +16 -6
  9. data/lib/ransack/adapters/active_record/3.0/context.rb +32 -16
  10. data/lib/ransack/adapters/active_record/3.1/context.rb +32 -15
  11. data/lib/ransack/adapters/active_record/3.2/context.rb +1 -1
  12. data/lib/ransack/adapters/active_record/base.rb +9 -6
  13. data/lib/ransack/adapters/active_record/context.rb +193 -2
  14. data/lib/ransack/configuration.rb +4 -4
  15. data/lib/ransack/constants.rb +81 -18
  16. data/lib/ransack/context.rb +27 -12
  17. data/lib/ransack/helpers/form_builder.rb +126 -91
  18. data/lib/ransack/helpers/form_helper.rb +34 -12
  19. data/lib/ransack/naming.rb +2 -1
  20. data/lib/ransack/nodes/attribute.rb +6 -4
  21. data/lib/ransack/nodes/bindable.rb +3 -1
  22. data/lib/ransack/nodes/condition.rb +40 -27
  23. data/lib/ransack/nodes/grouping.rb +19 -13
  24. data/lib/ransack/nodes/node.rb +3 -3
  25. data/lib/ransack/nodes/sort.rb +5 -3
  26. data/lib/ransack/nodes/value.rb +2 -2
  27. data/lib/ransack/predicate.rb +18 -9
  28. data/lib/ransack/ransacker.rb +4 -4
  29. data/lib/ransack/search.rb +9 -12
  30. data/lib/ransack/translate.rb +42 -21
  31. data/lib/ransack/version.rb +1 -1
  32. data/lib/ransack/visitor.rb +4 -4
  33. data/ransack.gemspec +17 -7
  34. data/spec/blueprints/notes.rb +2 -0
  35. data/spec/blueprints/people.rb +4 -1
  36. data/spec/console.rb +3 -3
  37. data/spec/ransack/adapters/active_record/base_spec.rb +149 -22
  38. data/spec/ransack/adapters/active_record/context_spec.rb +5 -5
  39. data/spec/ransack/configuration_spec.rb +17 -8
  40. data/spec/ransack/dependencies_spec.rb +8 -0
  41. data/spec/ransack/helpers/form_builder_spec.rb +37 -14
  42. data/spec/ransack/helpers/form_helper_spec.rb +5 -5
  43. data/spec/ransack/predicate_spec.rb +6 -3
  44. data/spec/ransack/search_spec.rb +95 -73
  45. data/spec/ransack/translate_spec.rb +14 -0
  46. data/spec/spec_helper.rb +14 -8
  47. data/spec/support/en.yml +6 -0
  48. data/spec/support/schema.rb +76 -31
  49. metadata +48 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aa2e8ee70ef82d95b0bc2c83e0005505252e2b13
4
- data.tar.gz: ae83094fdd4be127ba5471b48442a6c1f2922680
3
+ metadata.gz: 1b7aa5bc2bb1d2e9d78aea7431f3f3124b09ffdb
4
+ data.tar.gz: f16d483b98b63bd8d427678a185cb8ce7e6e56a3
5
5
  SHA512:
6
- metadata.gz: f2d9b0b0be3432472e801b0fdbfc19075a71461bba475c64f0cafa7cc32f9b8606b9136488fd7e1f1ef0dc34b7f2877815d32fc30a626ad74c3c75d21422e1b8
7
- data.tar.gz: dbb0b40594df15a6e7321d97e9ba134402168facc2de41b9a07cdf58683bb172f61aa01a6f5a61c5f73d6ff7053c597e2ce13b3b942cba2aea1b79f67de614cd
6
+ metadata.gz: 03ca0f504276420d2bc2f3ed1b2e2685091043f01fac0bcf538802d8ddae0ba6ee8c4fc36224d12aaf955beb3f709581dd7a207ef9b98a4eb10af136c0c38f2f
7
+ data.tar.gz: f77643a092da8bc3119b4f85d8cdc90977df7b78fc8738b3c0a490d18a21c492bed5e84df349bf4d3214016783c32ae07a82f14ea48435d94abbc63774af72b8
@@ -1,9 +1,16 @@
1
+ language: ruby
2
+
3
+ before_install:
4
+ - travis_retry gem install bundler
5
+
1
6
  rvm:
2
- - 1.9.3
3
7
  - 2.0.0
4
8
 
5
9
  env:
6
- - RAILS=4-0-stable DB=sqlite
10
+ - RAILS=4-1-stable DB=sqlite3
11
+ - RAILS=4-1-stable DB=mysql
12
+ - RAILS=4-1-stable DB=postgres
13
+ - RAILS=4-0-stable DB=sqlite3
7
14
  - RAILS=4-0-stable DB=mysql
8
15
  - RAILS=4-0-stable DB=postgres
9
16
  - RAILS=3-2-stable DB=sqlite
@@ -17,5 +24,6 @@ env:
17
24
  - RAILS=3-0-stable DB=postgres
18
25
 
19
26
  before_script:
20
- - mysql -e 'create database ransack;'
21
- - psql -c 'create database ransack;' -U postgres
27
+ - mysql -e 'create database ransack collate utf8_general_ci;'
28
+ - mysql -e 'use ransack;show variables like "%character%";show variables like "%collation%";'
29
+ - psql -c 'create database ransack;' -U postgres
@@ -8,13 +8,17 @@ When filing an issue on the Ransack project, please provide these details:
8
8
  * The version of Ransack *and* the version of Rails.
9
9
  * Any relevant stack traces ("Full trace" preferred)
10
10
 
11
- In 99% of cases, this information is enough to determine the cause and solution to the problem that is being described.
11
+ In 99% of cases, this information is enough to determine the cause and
12
+ solution to the problem that is being described.
12
13
 
13
- Any issue that is open for 14 days without actionable information or activity will be marked as "stalled" and then closed. Stalled issues can be re-opened if the information requested is provided.
14
+ Any issue that is open for 14 days without actionable information or activity
15
+ will be marked as "stalled" and then closed. Stalled issues can be re-opened
16
+ if the information requested is provided.
14
17
 
15
18
  ## Pull requests
16
19
 
17
- We gladly accept pull requests to fix bugs and, in some circumstances, add new features to Ransack.
20
+ We gladly accept pull requests to fix bugs and, in some circumstances, add new
21
+ features to Ransack.
18
22
 
19
23
  Here's a quick guide:
20
24
 
@@ -32,7 +36,9 @@ a test!
32
36
 
33
37
  4. Make the test pass.
34
38
 
35
- 5. Push to your fork and submit a pull request. If the changes will apply cleanly to the latest stable branches and master branch, you will only need to submit one pull request.
39
+ 5. Push to your fork and submit a pull request. If the changes will apply
40
+ cleanly to the latest stable branches and master branch, you will only need
41
+ to submit one pull request.
36
42
 
37
43
  At this point you're waiting on us. We like to at least comment on, if not
38
44
  accept, pull requests within three business days (and, typically, one business
data/Gemfile CHANGED
@@ -1,30 +1,33 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
4
  gem 'rake'
5
5
 
6
- rails = ENV['RAILS'] || '4-0-stable'
6
+ rails = ENV['RAILS'] || 'master'
7
7
 
8
- gem 'arel'
8
+ gem 'polyamorous', github: 'activerecord-hackery/polyamorous'
9
9
 
10
10
  case rails
11
11
  when /\// # A path
12
- gem 'activesupport', :path => "#{rails}/activesupport"
13
- gem 'activemodel', :path => "#{rails}/activemodel"
14
- gem 'activerecord', :path => "#{rails}/activerecord"
15
- gem 'actionpack', :path => "#{rails}/activerecord"
12
+ gem 'activesupport', path: "#{rails}/activesupport"
13
+ gem 'activemodel', path: "#{rails}/activemodel"
14
+ gem 'activerecord', path: "#{rails}/activerecord"
15
+ gem 'actionpack', path: "#{rails}/activerecord"
16
16
  when /^v/ # A tagged version
17
- git 'git://github.com/rails/rails.git', :tag => rails do
17
+ git 'git://github.com/rails/rails.git', tag: rails do
18
18
  gem 'activesupport'
19
19
  gem 'activemodel'
20
20
  gem 'activerecord'
21
21
  gem 'actionpack'
22
22
  end
23
23
  else
24
- git 'git://github.com/rails/rails.git', :branch => rails do
24
+ git 'git://github.com/rails/rails.git', branch: rails do
25
25
  gem 'activesupport'
26
26
  gem 'activemodel'
27
27
  gem 'activerecord'
28
28
  gem 'actionpack'
29
29
  end
30
+ if rails == '3-0-stable'
31
+ gem 'mysql2', '< 0.3'
32
+ end
30
33
  end
data/README.md CHANGED
@@ -1,29 +1,42 @@
1
1
  # Ransack
2
2
 
3
- [![Build Status](https://travis-ci.org/ernie/ransack.png?branch=master)](https://travis-ci.org/ernie/ransack)
3
+ [![Build Status](https://travis-ci.org/activerecord-hackery/ransack.svg)](https://travis-ci.org/activerecord-hackery/ransack)
4
4
 
5
- Ransack is a rewrite of [MetaSearch](https://github.com/ernie/meta_search). While it
5
+ Ransack is a rewrite of [MetaSearch](https://github.com/activerecord-hackery/meta_search) created by [Ernie Miller](http://twitter.com/erniemiller) and maintained by [Ryan Bigg](http://twitter.com/ryanbigg), [Jon Atack](http://twitter.com/jonatack) and a great group of [contributors](https://github.com/activerecord-hackery/ransack/graphs/contributors). While it
6
6
  supports many of the same features as MetaSearch, its underlying implementation differs
7
7
  greatly from MetaSearch, and _backwards compatibility is not a design goal._
8
8
 
9
9
  Ransack enables the creation of both simple and [advanced](http://ransack-demo.herokuapp.com/users/advanced_search)
10
- search forms against your application's models. If you're looking for something that
10
+ search forms against your application's models (demo source code [here](https://github.com/activerecord-hackery/ransack_demo)). If you're looking for something that
11
11
  simplifies query generation at the model or controller layer, you're probably not looking
12
12
  for Ransack (or MetaSearch, for that matter). Try
13
- [Squeel](https://github.com/ernie/squeel) instead.
13
+ [Squeel](https://github.com/activerecord-hackery/squeel) instead.
14
14
 
15
15
  ## Getting started
16
16
 
17
17
  In your Gemfile:
18
18
 
19
19
  ```ruby
20
- gem "ransack" # Last officially released gem (Rails 3 and 4)
20
+ gem "ransack" # Last officially released gem (compatible Rails 3.x and 4.0, but not 4.1)
21
21
  ```
22
22
 
23
- Or if you want to use the bleeding edge:
23
+ Or if you want to use the latest updates (Rails 3.x and 4.0, but not 4.1):
24
24
 
25
25
  ```ruby
26
- gem "ransack", github: "ernie/ransack" # Track git repo
26
+ gem "ransack", github: "activerecord-hackery/ransack" # Track git repo
27
+ ```
28
+
29
+ If you are on Rails 4.0, you may prefer to use the streamlined, legacy code-free, latest-updates version of Ransack on the [Rails 4 branch](https://github.com/activerecord-hackery/ransack/tree/rails-4):
30
+
31
+ ```ruby
32
+ gem "ransack", github: "activerecord-hackery/ransack", branch: "rails-4"
33
+ ```
34
+
35
+ Finally, if you are on Rails 4.1 (or 4.2.0.alpha), use the [Rails 4.1 branch](https://github.com/activerecord-hackery/ransack/tree/rails-4.1) which contains the latest updates also on master and rails-4. In your Gemfile you'll need to include (for the moment) both Ransack and Polyamorous as follows:
36
+
37
+ ```ruby
38
+ gem "ransack", github: "activerecord-hackery/ransack", branch: "rails-4.1"
39
+ gem "polyamorous", github: "activerecord-hackery/polyamorous"
27
40
  ```
28
41
 
29
42
  ## Usage
@@ -41,9 +54,11 @@ If you're coming from MetaSearch, things to note:
41
54
  primarily to shorten query strings, though advanced queries (below) will still
42
55
  run afoul of URL length limits in most browsers and require a switch to HTTP
43
56
  POST requests. This key is
44
- [configurable](https://github.com/ernie/ransack/wiki/Configuration)
57
+ [configurable](https://github.com/activerecord-hackery/ransack/wiki/Configuration).
58
+
45
59
  2. `form_for` is now `search_form_for`, and validates that a Ransack::Search object
46
60
  is passed to it.
61
+
47
62
  3. Common ActiveRecord::Relation methods are no longer delegated by the search object.
48
63
  Instead, you will get your search results (an ActiveRecord::Relation in the case of
49
64
  the ActiveRecord adapter) via a call to `Search#result`. If passed `distinct: true`,
@@ -78,7 +93,7 @@ In your view:
78
93
  ```
79
94
 
80
95
  `cont` (contains) and `start` (starts with) are just two of the available search predicates.
81
- See [Constants](https://github.com/ernie/ransack/blob/master/lib/ransack/constants.rb) for a full list and the [wiki](https://github.com/ernie/ransack/wiki/Basic-Searching) for more description.
96
+ See [Constants](https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/constants.rb) for a full list and the [wiki](https://github.com/activerecord-hackery/ransack/wiki/Basic-Searching) for more description.
82
97
 
83
98
  ### Advanced Mode
84
99
 
@@ -116,7 +131,16 @@ end
116
131
 
117
132
  Once you've done so, you can make use of the helpers in Ransack::Helpers::FormBuilder to
118
133
  construct much more complex search forms, such as the one on the
119
- [demo page](http://ransack-demo.heroku.com).
134
+ [demo page](http://ransack-demo.heroku.com) (source code [here](https://github.com/activerecord-hackery/ransack_demo)).
135
+
136
+ ### Ransack #search method
137
+
138
+ 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:
139
+
140
+ ```
141
+ Article.search(params[:q])
142
+ Article.ransack(params[:q])
143
+ ```
120
144
 
121
145
  ### has_many and belongs_to associations
122
146
 
@@ -173,6 +197,17 @@ end
173
197
  <% end %>
174
198
  ```
175
199
 
200
+ ## Using SimpleForm
201
+
202
+ If you want to combine form builders of ransack and SimpleForm, just set the RANSACK_FORM_BUILDER environment variable before Rails started, e.g. in ``config/application.rb`` before ``require 'rails/all'`` and of course use ``gem 'simple_form'`` in your ``Gemfile``:
203
+ ```ruby
204
+ require File.expand_path('../boot', __FILE__)
205
+
206
+ ENV['RANSACK_FORM_BUILDER'] = '::SimpleForm::FormBuilder'
207
+
208
+ require 'rails/all'
209
+ ```
210
+
176
211
  ## I18n
177
212
 
178
213
  Take a look at our locale file on ``lib/ransack/locale/en.yml`` to check all available messages. You may also be interested in one of the many translations that are available on:
@@ -190,4 +225,4 @@ To support the project:
190
225
 
191
226
  ## Copyright
192
227
 
193
- Copyright &copy; 2011 [Ernie Miller](http://twitter.com/erniemiller)
228
+ Copyright &copy; 2011-2014 [Ernie Miller](http://twitter.com/erniemiller)
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext'
2
+
1
3
  require 'ransack/configuration'
2
4
 
3
5
  module Ransack
@@ -8,7 +10,7 @@ end
8
10
 
9
11
  Ransack.configure do |config|
10
12
  Ransack::Constants::AREL_PREDICATES.each do |name|
11
- config.add_predicate name, :arel_predicate => name
13
+ config.add_predicate name, arel_predicate: name
12
14
  end
13
15
 
14
16
  Ransack::Constants::DERIVED_PREDICATES.each do |args|
@@ -23,4 +25,4 @@ require 'ransack/adapters/active_record' if defined?(::ActiveRecord::Base)
23
25
  require 'ransack/helpers'
24
26
  require 'action_controller'
25
27
 
26
- ActionController::Base.helper Ransack::Helpers::FormHelper
28
+ ActionController::Base.helper Ransack::Helpers::FormHelper
@@ -10,4 +10,4 @@ when /^3\.2\./
10
10
  require 'ransack/adapters/active_record/3.2/context'
11
11
  else
12
12
  require 'ransack/adapters/active_record/context'
13
- end
13
+ end
@@ -2,7 +2,7 @@
2
2
  if Arel::Nodes::And < Arel::Nodes::Binary
3
3
  class Ransack::Visitor
4
4
  def visit_Ransack_Nodes_And(object)
5
- nodes = object.values.map {|o| accept(o)}.compact
5
+ nodes = object.values.map { |o| accept(o) }.compact
6
6
  return nil unless nodes.size > 0
7
7
 
8
8
  if nodes.size > 1
@@ -132,9 +132,15 @@ module Arel
132
132
  end
133
133
 
134
134
  def visit_Arel_Nodes_NamedFunction o
135
- "#{o.name}(#{o.distinct ? 'DISTINCT ' : ''}#{o.expressions.map { |x|
136
- visit x
137
- }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
135
+ "#{
136
+ o.name
137
+ }(#{
138
+ o.distinct ? 'DISTINCT ' : ''
139
+ }#{
140
+ o.expressions.map { |x| visit x }.join(', ')
141
+ })#{
142
+ o.alias ? " AS #{visit o.alias}" : ''
143
+ }"
138
144
  end
139
145
 
140
146
  def visit_Arel_Nodes_And o
@@ -146,13 +152,17 @@ module Arel
146
152
  end
147
153
 
148
154
  def visit_Arel_Nodes_Values o
149
- "VALUES (#{o.expressions.zip(o.columns).map { |value, attr|
155
+ "VALUES (#{
156
+ o.expressions.zip(o.columns)
157
+ .map { |value, attr|
150
158
  if Nodes::SqlLiteral === value
151
159
  visit_Arel_Nodes_SqlLiteral value
152
160
  else
153
161
  quote(value, attr && column_for(attr))
154
162
  end
155
- }.join ', '})"
163
+ }
164
+ .join ', '
165
+ })"
156
166
  end
157
167
  end
158
168
  end
@@ -26,9 +26,11 @@ module Ransack
26
26
  viz = Visitor.new
27
27
  relation = @object.where(viz.accept(search.base))
28
28
  if search.sorts.any?
29
- relation = relation.except(:order).reorder(viz.accept(search.sorts))
29
+ relation = relation.except(:order)
30
+ .reorder(viz.accept(search.sorts))
30
31
  end
31
- opts[:distinct] ? relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
32
+ opts[:distinct] ?
33
+ relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
32
34
  end
33
35
 
34
36
  def attribute_method?(str, klass = @klass)
@@ -39,10 +41,15 @@ module Ransack
39
41
  elsif (segments = str.split(/_/)).size > 1
40
42
  remainder = []
41
43
  found_assoc = nil
42
- while !found_assoc && remainder.unshift(segments.pop) && segments.size > 0 do
43
- assoc, poly_class = unpolymorphize_association(segments.join('_'))
44
+ while !found_assoc && remainder.unshift(segments.pop) &&
45
+ segments.size > 0 do
46
+ assoc, poly_class = unpolymorphize_association(
47
+ segments.join('_')
48
+ )
44
49
  if found_assoc = get_association(assoc, klass)
45
- exists = attribute_method?(remainder.join('_'), poly_class || found_assoc.klass)
50
+ exists = attribute_method?(
51
+ remainder.join('_'), poly_class || found_assoc.klass
52
+ )
46
53
  end
47
54
  end
48
55
  end
@@ -56,7 +63,9 @@ module Ransack
56
63
 
57
64
  def type_for(attr)
58
65
  return nil unless attr && attr.valid?
59
- klassify(attr.parent).columns_hash[attr.arel_attribute.name.to_s].type
66
+ klassify(attr.parent)
67
+ .columns_hash[attr.arel_attribute.name.to_s]
68
+ .type
60
69
  end
61
70
 
62
71
  private
@@ -69,22 +78,26 @@ module Ransack
69
78
  elsif (segments = str.split(/_/)).size > 1
70
79
  remainder = []
71
80
  found_assoc = nil
72
- while remainder.unshift(segments.pop) && segments.size > 0 && !found_assoc do
81
+ while remainder.unshift(segments.pop) && segments.size > 0 &&
82
+ !found_assoc do
73
83
  assoc, klass = unpolymorphize_association(segments.join('_'))
74
84
  if found_assoc = get_association(assoc, parent)
75
- join = build_or_find_association(found_assoc.name, parent, klass)
76
- parent, attr_name = get_parent_and_attribute_name(remainder.join('_'), join)
85
+ join = build_or_find_association(
86
+ found_assoc.name, parent, klass
87
+ )
88
+ parent, attr_name = get_parent_and_attribute_name(
89
+ remainder.join('_'), join
90
+ )
77
91
  end
78
92
  end
79
93
  end
80
-
81
94
  [parent, attr_name]
82
95
  end
83
96
 
84
97
  def get_association(str, parent = @base)
85
98
  klass = klassify parent
86
99
  ransackable_association?(str, klass) &&
87
- klass.reflect_on_all_associations.detect {|a| a.name.to_s == str}
100
+ klass.reflect_on_all_associations.detect { |a| a.name.to_s == str }
88
101
  end
89
102
 
90
103
  def join_dependency(relation)
@@ -114,9 +127,9 @@ module Ransack
114
127
  association_joins = buckets['association_join'] || []
115
128
  stashed_association_joins = buckets['stashed_join'] || []
116
129
  join_nodes = buckets['join_node'] || []
117
- string_joins = (buckets['string_join'] || []).map { |x|
118
- x.strip
119
- }.uniq
130
+ string_joins = (buckets['string_join'] || [])
131
+ .map { |x| x.strip }
132
+ .uniq
120
133
 
121
134
  join_list = relation.send :custom_join_sql, (string_joins + join_nodes)
122
135
 
@@ -134,13 +147,16 @@ module Ransack
134
147
  end
135
148
 
136
149
  def build_or_find_association(name, parent = @base, klass = nil)
137
- found_association = @join_dependency.join_associations.detect do |assoc|
150
+ found_association = @join_dependency.join_associations
151
+ .detect do |assoc|
138
152
  assoc.reflection.name == name &&
139
153
  assoc.parent == parent &&
140
154
  (!klass || assoc.reflection.klass == klass)
141
155
  end
142
156
  unless found_association
143
- @join_dependency.send(:build, Polyamorous::Join.new(name, @join_type, klass), parent)
157
+ @join_dependency.send(
158
+ :build, Polyamorous::Join.new(name, @join_type, klass), parent
159
+ )
144
160
  found_association = @join_dependency.join_associations.last
145
161
  # Leverage the stashed association functionality in AR
146
162
  @object = @object.joins(found_association)
@@ -25,9 +25,12 @@ module Ransack
25
25
  viz = Visitor.new
26
26
  relation = @object.where(viz.accept(search.base))
27
27
  if search.sorts.any?
28
- relation = relation.except(:order).reorder(viz.accept(search.sorts))
28
+ relation = relation.except(:order)
29
+ .reorder(viz.accept(search.sorts))
29
30
  end
30
- opts[:distinct] ? relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
31
+ opts[:distinct] ?
32
+ relation.select("DISTINCT #{@klass.quoted_table_name}.*") :
33
+ relation
31
34
  end
32
35
 
33
36
  def attribute_method?(str, klass = @klass)
@@ -38,10 +41,15 @@ module Ransack
38
41
  elsif (segments = str.split(/_/)).size > 1
39
42
  remainder = []
40
43
  found_assoc = nil
41
- while !found_assoc && remainder.unshift(segments.pop) && segments.size > 0 do
42
- assoc, poly_class = unpolymorphize_association(segments.join('_'))
44
+ while !found_assoc && remainder.unshift(segments.pop) &&
45
+ segments.size > 0 do
46
+ assoc, poly_class = unpolymorphize_association(
47
+ segments.join('_')
48
+ )
43
49
  if found_assoc = get_association(assoc, klass)
44
- exists = attribute_method?(remainder.join('_'), poly_class || found_assoc.klass)
50
+ exists = attribute_method?(
51
+ remainder.join('_'), poly_class || found_assoc.klass
52
+ )
45
53
  end
46
54
  end
47
55
  end
@@ -75,11 +83,16 @@ module Ransack
75
83
  elsif (segments = str.split(/_/)).size > 1
76
84
  remainder = []
77
85
  found_assoc = nil
78
- while remainder.unshift(segments.pop) && segments.size > 0 && !found_assoc do
86
+ while remainder.unshift(segments.pop) && segments.size > 0 &&
87
+ !found_assoc do
79
88
  assoc, klass = unpolymorphize_association(segments.join('_'))
80
89
  if found_assoc = get_association(assoc, parent)
81
- join = build_or_find_association(found_assoc.name, parent, klass)
82
- parent, attr_name = get_parent_and_attribute_name(remainder.join('_'), join)
90
+ join = build_or_find_association(
91
+ found_assoc.name, parent, klass
92
+ )
93
+ parent, attr_name = get_parent_and_attribute_name(
94
+ remainder.join('_'), join
95
+ )
83
96
  end
84
97
  end
85
98
  end
@@ -90,7 +103,7 @@ module Ransack
90
103
  def get_association(str, parent = @base)
91
104
  klass = klassify parent
92
105
  ransackable_association?(str, klass) &&
93
- klass.reflect_on_all_associations.detect {|a| a.name.to_s == str}
106
+ klass.reflect_on_all_associations.detect { |a| a.name.to_s == str }
94
107
  end
95
108
 
96
109
  def join_dependency(relation)
@@ -120,11 +133,12 @@ module Ransack
120
133
  association_joins = buckets['association_join'] || []
121
134
  stashed_association_joins = buckets['stashed_join'] || []
122
135
  join_nodes = buckets['join_node'] || []
123
- string_joins = (buckets['string_join'] || []).map { |x|
124
- x.strip
125
- }.uniq
136
+ string_joins = (buckets['string_join'] || [])
137
+ .map { |x| x.strip }
138
+ .uniq
126
139
 
127
- join_list = relation.send :custom_join_ast, relation.table.from(relation.table), string_joins
140
+ join_list = relation.send :custom_join_ast,
141
+ relation.table.from(relation.table), string_joins
128
142
 
129
143
  join_dependency = JoinDependency.new(
130
144
  relation.klass,
@@ -140,13 +154,16 @@ module Ransack
140
154
  end
141
155
 
142
156
  def build_or_find_association(name, parent = @base, klass = nil)
143
- found_association = @join_dependency.join_associations.detect do |assoc|
157
+ found_association = @join_dependency.join_associations
158
+ .detect do |assoc|
144
159
  assoc.reflection.name == name &&
145
160
  assoc.parent == parent &&
146
161
  (!klass || assoc.reflection.klass == klass)
147
162
  end
148
163
  unless found_association
149
- @join_dependency.send(:build, Polyamorous::Join.new(name, @join_type, klass), parent)
164
+ @join_dependency.send(
165
+ :build, Polyamorous::Join.new(name, @join_type, klass), parent
166
+ )
150
167
  found_association = @join_dependency.join_associations.last
151
168
  # Leverage the stashed association functionality in AR
152
169
  @object = @object.joins(found_association)