ransack_abbreviator 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ransack_abbreviator/abbreviators/decoder.rb +33 -6
- data/lib/ransack_abbreviator/abbreviators/encoder.rb +13 -7
- data/lib/ransack_abbreviator/adapters/active_record/base.rb +4 -2
- data/lib/ransack_abbreviator/ransack_extensions/context.rb +30 -4
- data/lib/ransack_abbreviator/ransack_extensions/nodes/condition.rb +1 -2
- data/lib/ransack_abbreviator/ransack_extensions/search.rb +12 -16
- data/lib/ransack_abbreviator/version.rb +1 -1
- data/lib/ransack_abbreviator.rb +0 -1
- data/spec/ransack_abbreviator/search_spec.rb +25 -0
- metadata +1 -2
- data/lib/ransack_abbreviator/ransack_extensions/nodes/grouping.rb +0 -18
@@ -1,9 +1,36 @@
|
|
1
1
|
module RansackAbbreviator
|
2
2
|
module Abbreviators
|
3
|
-
|
3
|
+
class Decoder
|
4
|
+
attr_reader :context
|
5
|
+
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
|
+
end
|
9
|
+
|
10
|
+
def decode_parameter(param)
|
11
|
+
str = param.dup
|
12
|
+
pred = Ransack::Predicate.detect_and_strip_from_string!(str)
|
13
|
+
decoded_param = nil
|
14
|
+
case str
|
15
|
+
when /^(g|c|m|groupings|conditions|combinator)=?$/
|
16
|
+
decoded_param = param
|
17
|
+
else
|
18
|
+
conjunctions = str.split("_").select{|s| s == "and" || s == "or" }
|
19
|
+
decoded_param = ""
|
20
|
+
str.split(/_and_|_or_/).each do |possible_abbr|
|
21
|
+
decoded_str = self.context.decode_possible_abbr(possible_abbr)
|
22
|
+
decoded_param << (!decoded_str.blank? ? decoded_str : possible_abbr)
|
23
|
+
decoded_param << "_#{conjunctions.shift}_" if !conjunctions.blank?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
decoded_param << "_#{pred}" if pred
|
28
|
+
decoded_param
|
29
|
+
end
|
30
|
+
|
4
31
|
def decode_possible_abbr(possible_abbr)
|
5
32
|
possible_assoc_abbr, possible_attr_abbr = extract_possible_assoc_and_attribute_abbr(possible_abbr)
|
6
|
-
parent_of_attribute =
|
33
|
+
parent_of_attribute = @context.klass
|
7
34
|
decoded_str = ""
|
8
35
|
if possible_assoc_abbr
|
9
36
|
decoded_str, parent_of_attribute = decode_assoc_abbr(possible_assoc_abbr)
|
@@ -24,11 +51,11 @@ module RansackAbbreviator
|
|
24
51
|
decoded_str = ""
|
25
52
|
segments = possible_assoc_abbr.split(/_/)
|
26
53
|
association_parts = []
|
27
|
-
klass =
|
54
|
+
klass = @context.klass
|
28
55
|
|
29
56
|
while segments.size > 0 && association_parts << segments.shift
|
30
57
|
assoc_to_test = association_parts.join('_')
|
31
|
-
if polymorphic_association_specified?(assoc_to_test)
|
58
|
+
if Ransack::Context.polymorphic_association_specified?(assoc_to_test)
|
32
59
|
assoc_name, class_type = get_polymorphic_assoc_and_class_type(assoc_to_test)
|
33
60
|
klass = Kernel.const_get(class_type)
|
34
61
|
decoded_str << "of_#{class_type}_type_"
|
@@ -48,7 +75,7 @@ module RansackAbbreviator
|
|
48
75
|
[decoded_str, klass]
|
49
76
|
end
|
50
77
|
|
51
|
-
def decode_column_abbr(possible_attr_abbr, klass=@klass)
|
78
|
+
def decode_column_abbr(possible_attr_abbr, klass=@context.klass)
|
52
79
|
klass.ransackable_column_name_for(possible_attr_abbr)
|
53
80
|
end
|
54
81
|
|
@@ -57,7 +84,7 @@ module RansackAbbreviator
|
|
57
84
|
def get_polymorphic_assoc_and_class_type(possible_assoc_abbr)
|
58
85
|
assoc_name = class_type = nil
|
59
86
|
if (match = possible_assoc_abbr.match(/_of_([^_]+?)_type$/))
|
60
|
-
assoc_name =
|
87
|
+
assoc_name = @context.klass.ransackable_assoc_name_for(match.pre_match)
|
61
88
|
class_type = RansackAbbreviator.assoc_name_for(match.captures.first).camelize
|
62
89
|
end
|
63
90
|
[assoc_name, class_type]
|
@@ -1,17 +1,23 @@
|
|
1
1
|
module RansackAbbreviator
|
2
2
|
module Abbreviators
|
3
|
-
|
3
|
+
class Encoder
|
4
|
+
attr_reader :context
|
5
|
+
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
|
+
end
|
9
|
+
|
4
10
|
def encode_ransack_str(str)
|
5
11
|
encoded_str = ""
|
6
|
-
associations, attr_name =
|
7
|
-
parent_of_attribute =
|
12
|
+
associations, attr_name = @context.get_associations_and_attribute(str)
|
13
|
+
parent_of_attribute = @context.klass
|
8
14
|
|
9
15
|
if attr_name
|
10
16
|
unless associations.blank?
|
11
|
-
encoded_associations, parent_of_attribute =
|
17
|
+
encoded_associations, parent_of_attribute = encode_associations(associations, str)
|
12
18
|
encoded_str = "#{encoded_associations}."
|
13
19
|
end
|
14
|
-
encoded_str <<
|
20
|
+
encoded_str << encode_attribute(attr_name, parent_of_attribute)
|
15
21
|
else
|
16
22
|
encoded_str = str
|
17
23
|
end
|
@@ -20,7 +26,7 @@ module RansackAbbreviator
|
|
20
26
|
end
|
21
27
|
|
22
28
|
def encode_associations(associations, ransack_name)
|
23
|
-
klass =
|
29
|
+
klass = @context.klass
|
24
30
|
encoded_str = ""
|
25
31
|
|
26
32
|
associations.each_with_index do |assoc, i|
|
@@ -41,7 +47,7 @@ module RansackAbbreviator
|
|
41
47
|
[encoded_str, klass]
|
42
48
|
end
|
43
49
|
|
44
|
-
def encode_attribute(attr_name, parent=@klass)
|
50
|
+
def encode_attribute(attr_name, parent=@context.klass)
|
45
51
|
parent.ransackable_column_abbr_for(attr_name)
|
46
52
|
end
|
47
53
|
end
|
@@ -34,8 +34,10 @@ module RansackAbbreviator
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def ransackable_assoc_abbreviations
|
37
|
-
|
38
|
-
|
37
|
+
self._ransack_assoc_abbreviations ||= begin
|
38
|
+
associations = reflect_on_all_associations.map{|a| a.name.to_s}
|
39
|
+
RansackAbbreviator.assoc_abbreviations.select{ |key, val| associations.include?(key) }
|
40
|
+
end
|
39
41
|
end
|
40
42
|
|
41
43
|
def ransackable_column_name_for(possible_abbr)
|
@@ -3,8 +3,12 @@ require 'ransack_abbreviator/abbreviators/encoder'
|
|
3
3
|
|
4
4
|
module Ransack
|
5
5
|
class Context
|
6
|
-
|
7
|
-
|
6
|
+
attr_reader :decoder, :encoder
|
7
|
+
alias_method :full_ransackable_attribute?, :ransackable_attribute?
|
8
|
+
alias_method :full_ransackable_association?, :ransackable_association?
|
9
|
+
|
10
|
+
delegate :encode_ransack_str, to: :encoder
|
11
|
+
delegate :decode_parameter, :decode_possible_abbr, to: :decoder
|
8
12
|
|
9
13
|
def get_associations_and_attribute(str, klass = @klass, associations = [])
|
10
14
|
attr_name = nil
|
@@ -25,9 +29,31 @@ module Ransack
|
|
25
29
|
[associations, attr_name]
|
26
30
|
end
|
27
31
|
|
28
|
-
|
32
|
+
def decoder
|
33
|
+
@decoder ||= RansackAbbreviator::Abbreviators::Decoder.new(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
def encoder
|
37
|
+
@encoder ||= RansackAbbreviator::Abbreviators::Encoder.new(self)
|
38
|
+
end
|
39
|
+
|
40
|
+
def ransackable_attribute?(str, klass)
|
41
|
+
full_ransackable_attribute?(str, klass) || ransackable_attribute_abbreviation?(str, klass)
|
42
|
+
end
|
43
|
+
|
44
|
+
def ransackable_association?(str, klass)
|
45
|
+
full_ransackable_association?(str, klass) || ransackable_assoc_abbreviation?(str, klass)
|
46
|
+
end
|
47
|
+
|
48
|
+
def ransackable_attribute_abbreviation?(str, klass)
|
49
|
+
klass.ransackable_column_abbreviations.has_value?(str)
|
50
|
+
end
|
51
|
+
|
52
|
+
def ransackable_assoc_abbreviation?(str, klass)
|
53
|
+
klass.ransackable_assoc_abbreviations.has_value?(str)
|
54
|
+
end
|
29
55
|
|
30
|
-
def polymorphic_association_specified?(str)
|
56
|
+
def self.polymorphic_association_specified?(str)
|
31
57
|
str && str.match(/_of_([^_]+?)_type$/)
|
32
58
|
end
|
33
59
|
end
|
@@ -6,8 +6,7 @@ module Ransack
|
|
6
6
|
def build(params)
|
7
7
|
decoded_attr_names = []
|
8
8
|
params[:a].each do |possible_abbr|
|
9
|
-
|
10
|
-
decoded_attr_names << (!decoded_str.blank? ? decoded_str : possible_abbr)
|
9
|
+
decoded_attr_names << @context.decode_parameter(possible_abbr)
|
11
10
|
end
|
12
11
|
params[:a] = decoded_attr_names
|
13
12
|
ransack_condition_build(params)
|
@@ -1,27 +1,23 @@
|
|
1
1
|
module Ransack
|
2
2
|
class Search
|
3
3
|
alias_method :ransack_search_build, :build
|
4
|
+
alias_method :ransack_method_missing, :method_missing
|
5
|
+
|
6
|
+
def method_missing(method_id, *args)
|
7
|
+
method_name = method_id.to_s
|
8
|
+
writer = method_name.sub!(/\=$/, '')
|
9
|
+
# Decode abbreviation (if it is indeed an abbreviation) so Ransack is happy
|
10
|
+
decoded_param = self.context.decode_parameter(method_name)
|
11
|
+
decoded_str = writer ? "#{decoded_param}=" : decoded_param
|
12
|
+
ransack_method_missing(decoded_str.to_sym, *args)
|
13
|
+
end
|
4
14
|
|
5
15
|
def build(params)
|
6
16
|
# Loop through each of the params and test if any contain abbreviations. If so, convert them to the normal Ransack language
|
7
17
|
new_params = {}
|
8
18
|
collapse_multiparameter_attributes!(params.with_indifferent_access).each do |key, value|
|
9
|
-
|
10
|
-
|
11
|
-
if base.special_condition?(str)
|
12
|
-
# Maintain the param as-is
|
13
|
-
new_params[key] = value
|
14
|
-
else
|
15
|
-
conjunctions = str.split("_").select{|s| s == "and" || s == "or" }
|
16
|
-
full_str = ""
|
17
|
-
str.split(/_and_|_or_/).each do |possible_abbr|
|
18
|
-
decoded_str = self.context.decode_possible_abbr(possible_abbr)
|
19
|
-
full_str << (!decoded_str.blank? ? decoded_str : possible_abbr)
|
20
|
-
full_str << "_#{conjunctions.shift}_" if !conjunctions.blank?
|
21
|
-
end
|
22
|
-
full_str << "_#{pred}" if pred
|
23
|
-
new_params[full_str] = value
|
24
|
-
end
|
19
|
+
decoded_param = self.context.decode_parameter(key)
|
20
|
+
new_params[decoded_param] = value
|
25
21
|
end
|
26
22
|
|
27
23
|
ransack_search_build(new_params)
|
data/lib/ransack_abbreviator.rb
CHANGED
@@ -21,7 +21,6 @@ RansackAbbreviator.configure do |config|
|
|
21
21
|
end
|
22
22
|
|
23
23
|
require "ransack_abbreviator/ransack_extensions/nodes/condition"
|
24
|
-
require "ransack_abbreviator/ransack_extensions/nodes/grouping"
|
25
24
|
require "ransack_abbreviator/ransack_extensions/context"
|
26
25
|
require "ransack_abbreviator/ransack_extensions/search"
|
27
26
|
require 'ransack_abbreviator/adapters/active_record'
|
@@ -375,5 +375,30 @@ module Ransack # We're testing Ransack's Search wih abbreviations
|
|
375
375
|
search.result.where_values.first.to_sql.should eq abbr_search.result.where_values.first.to_sql
|
376
376
|
end
|
377
377
|
end
|
378
|
+
|
379
|
+
describe '#method_missing' do
|
380
|
+
before do
|
381
|
+
@search = Search.new(Person)
|
382
|
+
end
|
383
|
+
|
384
|
+
it 'support abbreviations' do
|
385
|
+
abbr_search = ransack_abbreviation_for(@search, :middle_name_eq)
|
386
|
+
@search.send "#{abbr_search}=", 'Ernie'
|
387
|
+
@search.middle_name_eq.should eq 'Ernie'
|
388
|
+
|
389
|
+
abbr_search = ransack_abbreviation_for(@search, :authored_article_comments_vote_count_lteq)
|
390
|
+
@search.send "#{abbr_search}=", 10
|
391
|
+
@search.authored_article_comments_vote_count_lteq.should eq 10
|
392
|
+
|
393
|
+
note_search = Search.new(Note)
|
394
|
+
abbr_search = ransack_abbreviation_for(note_search, :notable_of_Person_type_name_eq)
|
395
|
+
note_search.send "#{abbr_search}=", 'Ernie'
|
396
|
+
note_search.notable_of_Person_type_name_eq.should eq 'Ernie'
|
397
|
+
end
|
398
|
+
|
399
|
+
it 'raises NoMethodError when sent an invalid attribute/abreviation' do
|
400
|
+
expect {@search.i_am_garbage}.to raise_error NoMethodError
|
401
|
+
end
|
402
|
+
end
|
378
403
|
end
|
379
404
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ransack_abbreviator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jamie Davidson
|
@@ -104,7 +104,6 @@ files:
|
|
104
104
|
- lib/ransack_abbreviator/constants.rb
|
105
105
|
- lib/ransack_abbreviator/ransack_extensions/context.rb
|
106
106
|
- lib/ransack_abbreviator/ransack_extensions/nodes/condition.rb
|
107
|
-
- lib/ransack_abbreviator/ransack_extensions/nodes/grouping.rb
|
108
107
|
- lib/ransack_abbreviator/ransack_extensions/search.rb
|
109
108
|
- lib/ransack_abbreviator/version.rb
|
110
109
|
- lib/ransack_abbreviator/view_helpers.rb
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Ransack
|
2
|
-
module Nodes
|
3
|
-
class Grouping < Node
|
4
|
-
def strip_predicate_and_index_from_param_string(param_string)
|
5
|
-
strip_predicate_and_index(param_string)
|
6
|
-
end
|
7
|
-
|
8
|
-
def special_condition?(str)
|
9
|
-
case str
|
10
|
-
when /^(g|c|m|groupings|conditions|combinator)=?$/
|
11
|
-
true
|
12
|
-
else
|
13
|
-
false
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|