ransack_abbreviator 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|