ransack 2.1.0 → 2.4.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +32 -22
- data/CHANGELOG.md +60 -1
- data/CONTRIBUTING.md +11 -6
- data/Gemfile +21 -17
- data/README.md +56 -29
- data/lib/polyamorous/{activerecord_5.2.1_ruby_2 → activerecord_5.2_ruby_2}/join_association.rb +2 -9
- data/lib/polyamorous/{activerecord_5.2.1_ruby_2 → activerecord_5.2_ruby_2}/join_dependency.rb +25 -3
- data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +11 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +1 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +80 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +1 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +74 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +93 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +1 -0
- data/lib/{polyamorous.rb → polyamorous/polyamorous.rb} +3 -3
- data/lib/ransack.rb +2 -2
- data/lib/ransack/adapters/active_record/base.rb +1 -0
- data/lib/ransack/adapters/active_record/context.rb +60 -68
- data/lib/ransack/adapters/active_record/ransack/constants.rb +17 -2
- data/lib/ransack/adapters/active_record/ransack/context.rb +2 -6
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +12 -5
- data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -1
- data/lib/ransack/constants.rb +2 -3
- data/lib/ransack/context.rb +19 -18
- data/lib/ransack/helpers/form_builder.rb +5 -11
- data/lib/ransack/helpers/form_helper.rb +1 -1
- data/lib/ransack/locale/ar.yml +70 -0
- data/lib/ransack/locale/az.yml +1 -1
- data/lib/ransack/locale/ca.yml +70 -0
- data/lib/ransack/locale/es.yml +22 -22
- data/lib/ransack/locale/fa.yml +70 -0
- data/lib/ransack/locale/fi.yml +71 -0
- data/lib/ransack/locale/sk.yml +70 -0
- data/lib/ransack/locale/zh-CN.yml +12 -12
- data/lib/ransack/nodes/condition.rb +8 -0
- data/lib/ransack/nodes/grouping.rb +1 -1
- data/lib/ransack/predicate.rb +2 -1
- data/lib/ransack/search.rb +1 -0
- data/lib/ransack/translate.rb +115 -115
- data/lib/ransack/version.rb +1 -1
- data/ransack.gemspec +5 -21
- data/spec/helpers/polyamorous_helper.rb +3 -8
- data/spec/{ransack → polyamorous}/join_association_spec.rb +7 -0
- data/spec/{ransack → polyamorous}/join_dependency_spec.rb +18 -7
- data/spec/{ransack → polyamorous}/join_spec.rb +0 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +8 -8
- data/spec/ransack/adapters/active_record/context_spec.rb +60 -17
- data/spec/ransack/helpers/form_helper_spec.rb +51 -51
- data/spec/ransack/predicate_spec.rb +54 -2
- data/spec/ransack/search_spec.rb +78 -13
- data/spec/spec_helper.rb +4 -0
- data/spec/support/schema.rb +13 -2
- metadata +29 -136
- data/lib/polyamorous/activerecord_5.0_ruby_2/join_association.rb +0 -2
- data/lib/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb +0 -2
- data/lib/polyamorous/activerecord_5.1_ruby_2/join_association.rb +0 -32
- data/lib/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb +0 -112
- data/lib/polyamorous/activerecord_5.2.0_ruby_2/join_association.rb +0 -32
- data/lib/polyamorous/activerecord_5.2.0_ruby_2/join_dependency.rb +0 -113
@@ -0,0 +1,71 @@
|
|
1
|
+
fi:
|
2
|
+
ransack:
|
3
|
+
search: "haku"
|
4
|
+
predicate: "predikaatti"
|
5
|
+
and: "ja"
|
6
|
+
or: "tai"
|
7
|
+
any: "jokin"
|
8
|
+
all: "kaikki"
|
9
|
+
combinator: "kombinaattori"
|
10
|
+
attribute: "attribuutti"
|
11
|
+
value: "arvo"
|
12
|
+
condition: "ehto"
|
13
|
+
sort: "järjestys"
|
14
|
+
asc: "nouseva"
|
15
|
+
desc: "laskeva"
|
16
|
+
predicates:
|
17
|
+
eq: "sama kuin"
|
18
|
+
eq_any: "sama kuin jokin"
|
19
|
+
eq_all: "sama kuin kaikki"
|
20
|
+
not_eq: "eri kuin"
|
21
|
+
not_eq_any: "eri kuin jokin"
|
22
|
+
not_eq_all: "eri kuin kaikki"
|
23
|
+
matches: "täsmää"
|
24
|
+
matches_any: "täsmää jonkun kanssa"
|
25
|
+
matches_all: "täsmää kaikkien kanssa"
|
26
|
+
does_not_match: "ei täsmää"
|
27
|
+
does_not_match_any: "ei täsmää minkään kanssa"
|
28
|
+
does_not_match_all: "ei täsmää kaikkien kanssa"
|
29
|
+
lt: "vähemmän kuin"
|
30
|
+
lt_any: "vähemmän kuin jokin"
|
31
|
+
lt_all: "vähemmän kuin mikään"
|
32
|
+
lteq: "vähemmän tai sama kuin"
|
33
|
+
lteq_any: "vähemmän tai sama kuin jokin"
|
34
|
+
lteq_all: "vähemmän tai sama kuin mikään"
|
35
|
+
gt: "suurempi kuin"
|
36
|
+
gt_any: "suurempi kuin jokin"
|
37
|
+
gt_all: "suurempi kuin mikään"
|
38
|
+
gteq: "suurempi tai yhtä suuri kuin"
|
39
|
+
gteq_any: "suurempi tai yhtä suuri kuin jokin"
|
40
|
+
gteq_all: "suurempi tai yhtä suuri kuin mikään"
|
41
|
+
in: "kohteessa"
|
42
|
+
in_any: "jossakin kohteessa"
|
43
|
+
in_all: "kaikissa kohteissa"
|
44
|
+
not_in: "ei kohteessa"
|
45
|
+
not_in_any: "ei jossakin kohteista"
|
46
|
+
not_in_all: "ei missään kohteista"
|
47
|
+
cont: "sisältää"
|
48
|
+
cont_any: "sisältää jonkin"
|
49
|
+
cont_all: "sisältää kaikki"
|
50
|
+
not_cont: "ei sisällä"
|
51
|
+
not_cont_any: "ei sisällä jotakin"
|
52
|
+
not_cont_all: "ei sisällä mitään"
|
53
|
+
start: "alkaa"
|
54
|
+
start_any: "alkaa jollakin"
|
55
|
+
start_all: "alkaa kaikilla"
|
56
|
+
not_start: "ei ala"
|
57
|
+
not_start_any: "ei ala jollakin"
|
58
|
+
not_start_all: "ei ala millään"
|
59
|
+
end: "päättyy"
|
60
|
+
end_any: "päättyy jollakin"
|
61
|
+
end_all: "päättyy millään"
|
62
|
+
not_end: "ei pääty"
|
63
|
+
not_end_any: "ei pääty jollakin"
|
64
|
+
not_end_all: "ei pääty millään"
|
65
|
+
'true': "on tosi"
|
66
|
+
'false': "ei ole tosi"
|
67
|
+
present: "on läsnä"
|
68
|
+
blank: "on tyhjä"
|
69
|
+
'null': "on määrittämätön"
|
70
|
+
not_null: "on määritetty"
|
71
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
sk:
|
2
|
+
ransack:
|
3
|
+
search: "vyhľadávanie"
|
4
|
+
predicate: "predikát"
|
5
|
+
and: "a"
|
6
|
+
or: "alebo"
|
7
|
+
any: "akýkoľvek"
|
8
|
+
all: "každý"
|
9
|
+
combinator: "kombinátor"
|
10
|
+
attribute: "atribút"
|
11
|
+
value: "hodnota"
|
12
|
+
condition: "podmienka"
|
13
|
+
sort: "poradie"
|
14
|
+
asc: "vzostupne"
|
15
|
+
desc: "zostupne"
|
16
|
+
predicates:
|
17
|
+
eq: "sa rovná"
|
18
|
+
eq_any: "sa rovná akémukoľvek"
|
19
|
+
eq_all: "sa rovná všetkým"
|
20
|
+
not_eq: "sa nerovná"
|
21
|
+
not_eq_any: "sa nerovná akémukoľvek"
|
22
|
+
not_eq_all: "sa nerovná všetkým"
|
23
|
+
matches: "zodpovedá"
|
24
|
+
matches_any: "zodpovedá akémukoľvek"
|
25
|
+
matches_all: "zodpovedá všetkým"
|
26
|
+
does_not_match: "nezodpovedá"
|
27
|
+
does_not_match_any: "nezodpovedá akémukoľvek"
|
28
|
+
does_not_match_all: "nezodpovedá všetkým"
|
29
|
+
lt: "menší ako"
|
30
|
+
lt_any: "menší ako akýkoľvek"
|
31
|
+
lt_all: "menší ako všetky"
|
32
|
+
lteq: "menší alebo rovný"
|
33
|
+
lteq_any: "menší alebo rovný akémukoľvek"
|
34
|
+
lteq_all: "menší alebo rovný všetkým"
|
35
|
+
gt: "väčší ako"
|
36
|
+
gt_any: "väčší ako akýkoľvek"
|
37
|
+
gt_all: "väčší ako všetky"
|
38
|
+
gteq: "väčší alebo rovný"
|
39
|
+
gteq_any: "väčší alebo rovný akémukoľvek"
|
40
|
+
gteq_all: "väčší alebo rovný všetkým"
|
41
|
+
in: "v"
|
42
|
+
in_any: "v akejkoľvek"
|
43
|
+
in_all: "vo všetkých"
|
44
|
+
not_in: "nie je v"
|
45
|
+
not_in_any: "nie je v akejkoľvek"
|
46
|
+
not_in_all: "nie je vo všetkých"
|
47
|
+
cont: "obsahuje"
|
48
|
+
cont_any: "obsahuje akúkoľvek"
|
49
|
+
cont_all: "obsahuje všetky"
|
50
|
+
not_cont: "neobsahuje"
|
51
|
+
not_cont_any: "neobsahuje akúkoľvek"
|
52
|
+
not_cont_all: "neobsahuje všetky"
|
53
|
+
start: "začína na"
|
54
|
+
start_any: "začína s akoukoľvek"
|
55
|
+
start_all: "začína so všetkými"
|
56
|
+
not_start: "nezačíná s"
|
57
|
+
not_start_any: "nezačíná s akoukoľvek"
|
58
|
+
not_start_all: "nezačíná so všetkými"
|
59
|
+
end: "končí s"
|
60
|
+
end_any: "končí s akoukoľvek"
|
61
|
+
end_all: "končí so všetkými"
|
62
|
+
not_end: "nekončí s"
|
63
|
+
not_end_any: "nekončí s akoukoľvek"
|
64
|
+
not_end_all: "nekončí so všetkými"
|
65
|
+
'true': "je pravdivé"
|
66
|
+
'false': "nie je pravdivé"
|
67
|
+
present: "je vyplnené"
|
68
|
+
blank: "je prázdne"
|
69
|
+
'null': "je null"
|
70
|
+
not_null: "nie je null"
|
@@ -50,18 +50,18 @@ zh-CN:
|
|
50
50
|
not_cont: "不包含"
|
51
51
|
not_cont_any: "不包含任意一个值"
|
52
52
|
not_cont_all: "不包含所有值"
|
53
|
-
start: "
|
54
|
-
start_any: "
|
55
|
-
start_all: "
|
56
|
-
not_start: "
|
57
|
-
not_start_any: "
|
58
|
-
not_start_all: "
|
59
|
-
end: "
|
60
|
-
end_any: "
|
61
|
-
end_all: "
|
62
|
-
not_end: "
|
63
|
-
not_end_any: "
|
64
|
-
not_end_all: "
|
53
|
+
start: "始于"
|
54
|
+
start_any: "始于任一值"
|
55
|
+
start_all: "始于任意值"
|
56
|
+
not_start: "非始于"
|
57
|
+
not_start_any: "非始于任一值"
|
58
|
+
not_start_all: "非始于任意值"
|
59
|
+
end: "止于"
|
60
|
+
end_any: "止于任一值"
|
61
|
+
end_all: "止于任意值"
|
62
|
+
not_end: "非止于"
|
63
|
+
not_end_any: "非止于任一值"
|
64
|
+
not_end_all: "非止于任意值"
|
65
65
|
'true': "等于true"
|
66
66
|
'false': "等于false"
|
67
67
|
present: "有值"
|
@@ -255,6 +255,14 @@ module Ransack
|
|
255
255
|
end
|
256
256
|
end
|
257
257
|
|
258
|
+
def attr_value_for_attribute(attr)
|
259
|
+
return attr.attr if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
260
|
+
|
261
|
+
predicate.case_insensitive ? attr.attr.lower : attr.attr
|
262
|
+
rescue
|
263
|
+
attr.attr
|
264
|
+
end
|
265
|
+
|
258
266
|
|
259
267
|
def default_type
|
260
268
|
predicate.type || (attributes.first && attributes.first.type)
|
@@ -108,7 +108,7 @@ module Ransack
|
|
108
108
|
alias :g= :groupings=
|
109
109
|
|
110
110
|
def method_missing(method_id, *args)
|
111
|
-
method_name = method_id.to_s
|
111
|
+
method_name = method_id.to_s.dup
|
112
112
|
writer = method_name.sub!(/\=$/, ''.freeze)
|
113
113
|
if attribute_method?(method_name)
|
114
114
|
if writer
|
data/lib/ransack/predicate.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Ransack
|
2
2
|
class Predicate
|
3
3
|
attr_reader :name, :arel_predicate, :type, :formatter, :validator,
|
4
|
-
:compound, :wants_array
|
4
|
+
:compound, :wants_array, :case_insensitive
|
5
5
|
|
6
6
|
class << self
|
7
7
|
|
@@ -42,6 +42,7 @@ module Ransack
|
|
42
42
|
@compound = opts[:compound]
|
43
43
|
@wants_array = opts.fetch(:wants_array,
|
44
44
|
@compound || Constants::IN_NOT_IN.include?(@arel_predicate))
|
45
|
+
@case_insensitive = opts[:case_insensitive]
|
45
46
|
end
|
46
47
|
|
47
48
|
def eql?(other)
|
data/lib/ransack/search.rb
CHANGED
@@ -18,6 +18,7 @@ module Ransack
|
|
18
18
|
params = params.to_unsafe_h if params.respond_to?(:to_unsafe_h)
|
19
19
|
if params.is_a? Hash
|
20
20
|
params = params.dup
|
21
|
+
params = params.transform_values { |v| v.is_a?(String) ? v.strip : v }
|
21
22
|
params.delete_if { |k, v| [*v].all?{ |i| i.blank? && i != false } }
|
22
23
|
else
|
23
24
|
params = {}
|
data/lib/ransack/translate.rb
CHANGED
@@ -6,151 +6,151 @@ I18n.load_path += Dir[
|
|
6
6
|
|
7
7
|
module Ransack
|
8
8
|
module Translate
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def self.predicate(key, options = {})
|
14
|
-
I18n.translate(:"ransack.predicates.#{key}", :default => key.to_s)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.attribute(key, options = {})
|
18
|
-
unless context = options.delete(:context)
|
19
|
-
raise ArgumentError, "A context is required to translate attributes"
|
9
|
+
class << self
|
10
|
+
def word(key, options = {})
|
11
|
+
I18n.translate(:"ransack.#{key}", default: key.to_s)
|
20
12
|
end
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
base_ancestors = base_class.ancestors.select {
|
25
|
-
|x| x.respond_to?(:model_name)
|
26
|
-
}
|
27
|
-
attributes_str = original_name.dup # will be modified by ⬇
|
28
|
-
predicate = Predicate.detect_and_strip_from_string!(attributes_str)
|
29
|
-
attribute_names = attributes_str.split(/_and_|_or_/)
|
30
|
-
combinator = attributes_str.match(/_and_/) ? :and : :or
|
31
|
-
defaults = base_ancestors.map do |klass|
|
32
|
-
"ransack.attributes.#{i18n_key(klass)}.#{original_name}".to_sym
|
14
|
+
def predicate(key, options = {})
|
15
|
+
I18n.translate(:"ransack.predicates.#{key}", default: key.to_s)
|
33
16
|
end
|
34
17
|
|
35
|
-
|
36
|
-
|
37
|
-
|
18
|
+
def attribute(key, options = {})
|
19
|
+
unless context = options.delete(:context)
|
20
|
+
raise ArgumentError, "A context is required to translate attributes"
|
21
|
+
end
|
38
22
|
|
39
|
-
|
40
|
-
|
41
|
-
|
23
|
+
original_name = key.to_s
|
24
|
+
base_class = context.klass
|
25
|
+
base_ancestors = base_class.ancestors.select {
|
26
|
+
|x| x.respond_to?(:model_name)
|
27
|
+
}
|
28
|
+
attributes_str = original_name.dup # will be modified by ⬇
|
29
|
+
predicate = Predicate.detect_and_strip_from_string!(attributes_str)
|
30
|
+
attribute_names = attributes_str.split(/_and_|_or_/)
|
31
|
+
combinator = attributes_str =~ /_and_/ ? :and : :or
|
32
|
+
defaults = base_ancestors.map do |klass|
|
33
|
+
"ransack.attributes.#{i18n_key(klass)}.#{original_name}".to_sym
|
34
|
+
end
|
42
35
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
else
|
47
|
-
defaults << "%{attributes}".freeze
|
48
|
-
end
|
36
|
+
translated_names = attribute_names.map do |name|
|
37
|
+
attribute_name(context, name, options[:include_associations])
|
38
|
+
end
|
49
39
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
40
|
+
interpolations = {
|
41
|
+
attributes: translated_names.join(" #{Translate.word(combinator)} ")
|
42
|
+
}
|
54
43
|
|
55
|
-
|
56
|
-
|
57
|
-
|
44
|
+
if predicate
|
45
|
+
defaults << "%{attributes} %{predicate}".freeze
|
46
|
+
interpolations[:predicate] = Translate.predicate(predicate)
|
47
|
+
else
|
48
|
+
defaults << "%{attributes}".freeze
|
49
|
+
end
|
50
|
+
|
51
|
+
defaults << options.delete(:default) if options[:default]
|
52
|
+
options.reverse_merge! count: 1, default: defaults
|
53
|
+
I18n.translate(defaults.shift, **options.merge(interpolations))
|
58
54
|
end
|
59
55
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
:"#{context.klass.i18n_scope}.models.#{i18n_key(context.klass)}"]
|
64
|
-
else
|
65
|
-
[:"ransack.associations.#{i18n_key(context.klass)}.#{key}"]
|
56
|
+
def association(key, options = {})
|
57
|
+
unless context = options.delete(:context)
|
58
|
+
raise ArgumentError, "A context is required to translate associations"
|
66
59
|
end
|
67
|
-
defaults << context.traverse(key).model_name.human
|
68
|
-
options = { :count => 1, :default => defaults }
|
69
|
-
I18n.translate(defaults.shift, options)
|
70
|
-
end
|
71
60
|
|
72
|
-
|
61
|
+
defaults =
|
62
|
+
if key.blank?
|
63
|
+
[:"ransack.models.#{i18n_key(context.klass)}",
|
64
|
+
:"#{context.klass.i18n_scope}.models.#{i18n_key(context.klass)}"]
|
65
|
+
else
|
66
|
+
[:"ransack.associations.#{i18n_key(context.klass)}.#{key}"]
|
67
|
+
end
|
68
|
+
defaults << context.traverse(key).model_name.human
|
69
|
+
options = { :count => 1, :default => defaults }
|
70
|
+
I18n.translate(defaults.shift, **options)
|
71
|
+
end
|
73
72
|
|
74
|
-
|
75
|
-
@context, @name = context, name
|
76
|
-
@assoc_path = context.association_path(name)
|
77
|
-
@attr_name = @name.sub(/^#{@assoc_path}_/, ''.freeze)
|
78
|
-
associated_class = @context.traverse(@assoc_path) if @assoc_path.present?
|
79
|
-
@include_associated = include_associations && associated_class
|
73
|
+
private
|
80
74
|
|
81
|
-
|
82
|
-
|
83
|
-
|
75
|
+
def attribute_name(context, name, include_associations = nil)
|
76
|
+
@context, @name = context, name
|
77
|
+
@assoc_path = context.association_path(name)
|
78
|
+
@attr_name = @name.sub(/^#{@assoc_path}_/, ''.freeze)
|
79
|
+
associated_class = @context.traverse(@assoc_path) if @assoc_path.present?
|
80
|
+
@include_associated = include_associations && associated_class
|
84
81
|
|
85
|
-
|
86
|
-
|
82
|
+
defaults = default_attribute_name << fallback_args
|
83
|
+
options = { count: 1, default: defaults }
|
84
|
+
interpolations = build_interpolations(associated_class)
|
87
85
|
|
88
|
-
|
89
|
-
|
90
|
-
end
|
86
|
+
I18n.translate(defaults.shift, **options.merge(interpolations))
|
87
|
+
end
|
91
88
|
|
92
|
-
|
93
|
-
|
94
|
-
'%{association_name} %{attr_fallback_name}'.freeze
|
95
|
-
else
|
96
|
-
'%{attr_fallback_name}'.freeze
|
89
|
+
def default_attribute_name
|
90
|
+
["ransack.attributes.#{i18n_key(@context.klass)}.#{@name}".to_sym]
|
97
91
|
end
|
98
|
-
end
|
99
92
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
93
|
+
def fallback_args
|
94
|
+
if @include_associated
|
95
|
+
'%{association_name} %{attr_fallback_name}'.freeze
|
96
|
+
else
|
97
|
+
'%{attr_fallback_name}'.freeze
|
98
|
+
end
|
99
|
+
end
|
107
100
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
101
|
+
def build_interpolations(associated_class)
|
102
|
+
{
|
103
|
+
attr_fallback_name: attr_fallback_name(associated_class),
|
104
|
+
association_name: association_name
|
105
|
+
}.reject { |_, value| value.nil? }
|
106
|
+
end
|
107
|
+
|
108
|
+
def attr_fallback_name(associated_class)
|
109
|
+
I18n.t(
|
110
|
+
:"ransack.attributes.#{fallback_class(associated_class)}.#{@attr_name}",
|
111
|
+
default: default_interpolation(associated_class)
|
112
112
|
)
|
113
|
-
|
113
|
+
end
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
|
115
|
+
def fallback_class(associated_class)
|
116
|
+
i18n_key(associated_class || @context.klass)
|
117
|
+
end
|
118
118
|
|
119
|
-
|
120
|
-
|
121
|
-
|
119
|
+
def association_name
|
120
|
+
association(@assoc_path, context: @context) if @include_associated
|
121
|
+
end
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
123
|
+
def default_interpolation(associated_class)
|
124
|
+
[
|
125
|
+
associated_attribute(associated_class),
|
126
|
+
".attributes.#{@attr_name}".to_sym,
|
127
|
+
@attr_name.humanize
|
128
|
+
].flatten
|
129
|
+
end
|
131
130
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
131
|
+
def associated_attribute(associated_class)
|
132
|
+
if associated_class
|
133
|
+
translated_attribute(associated_class)
|
134
|
+
else
|
135
|
+
translated_ancestor_attributes
|
136
|
+
end
|
137
137
|
end
|
138
|
-
end
|
139
138
|
|
140
|
-
|
141
|
-
|
139
|
+
def translated_attribute(associated_class)
|
140
|
+
key = "#{associated_class.i18n_scope}.attributes.#{
|
142
141
|
i18n_key(associated_class)}.#{@attr_name}"
|
143
|
-
|
144
|
-
|
142
|
+
["#{key}.one".to_sym, key.to_sym]
|
143
|
+
end
|
145
144
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
145
|
+
def translated_ancestor_attributes
|
146
|
+
@context.klass.ancestors
|
147
|
+
.select { |ancestor| ancestor.respond_to?(:model_name) }
|
148
|
+
.map { |ancestor| translated_attribute(ancestor) }
|
149
|
+
end
|
151
150
|
|
152
|
-
|
153
|
-
|
151
|
+
def i18n_key(klass)
|
152
|
+
raise "not implemented"
|
153
|
+
end
|
154
154
|
end
|
155
155
|
end
|
156
156
|
end
|