json_translate 2.0.0 → 3.0.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/README.md +1 -1
- data/lib/json_translate/translates/active_record_with_json_translates.rb +22 -0
- data/lib/json_translate/translates/instance_methods.rb +98 -0
- data/lib/json_translate/translates.rb +15 -107
- data/lib/json_translate/version.rb +1 -1
- data/lib/json_translate.rb +4 -2
- data/test/gemfiles/Gemfile.rails-4.2.x +5 -0
- data/test/test_helper.rb +6 -1
- data/test/translates_test.rb +23 -0
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c63d1189154bdd9a3c4f9b1d166010983eb6aa2b
|
4
|
+
data.tar.gz: 8d8a04e3acb55be9adee7b2256adb5efb6c87d97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eda1091080675c5e1f75a8b65448b8fb850534a666b0336a3933ef917dccdb446aaca89e644c0a976fa348685df80500cfb536d5e9b34e4b133071b4b064e459
|
7
|
+
data.tar.gz: 8ba0d7fcdabcc207dafa2e0cd7e9ee2408b5667653d8f2ea7946ae7dc9e0466365a5bdaf075e59b8ed6b2a0b9857f830ced0e50f03993bca0cd424b988fe68e4
|
data/README.md
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
module JSONTranslate
|
2
|
+
module Translates
|
3
|
+
module ActiveRecordWithJSONTranslate
|
4
|
+
def respond_to?(symbol, include_all = false)
|
5
|
+
return true if parse_translated_attribute_accessor(symbol)
|
6
|
+
super(symbol, include_all)
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(method_name, *args)
|
10
|
+
translated_attr_name, locale, assigning = parse_translated_attribute_accessor(method_name)
|
11
|
+
|
12
|
+
return super(method_name, *args) unless translated_attr_name
|
13
|
+
|
14
|
+
if assigning
|
15
|
+
write_json_translation(translated_attr_name, args.first, locale)
|
16
|
+
else
|
17
|
+
read_json_translation(translated_attr_name, locale)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module JSONTranslate
|
2
|
+
module Translates
|
3
|
+
module InstanceMethods
|
4
|
+
def disable_fallback
|
5
|
+
toggle_fallback(false)
|
6
|
+
end
|
7
|
+
|
8
|
+
def enable_fallback
|
9
|
+
toggle_fallback(true)
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
attr_reader :enabled_fallback
|
15
|
+
|
16
|
+
def json_translate_fallback_locales(locale)
|
17
|
+
return locale if enabled_fallback == false || !I18n.respond_to?(:fallbacks)
|
18
|
+
I18n.fallbacks[locale]
|
19
|
+
end
|
20
|
+
|
21
|
+
def read_json_translation(attr_name, locale = I18n.locale)
|
22
|
+
translations = public_send("#{attr_name}#{SUFFIX}") || {}
|
23
|
+
|
24
|
+
available = Array(json_translate_fallback_locales(locale)).detect do |available_locale|
|
25
|
+
translations[available_locale.to_s].present?
|
26
|
+
end
|
27
|
+
|
28
|
+
translations[available.to_s]
|
29
|
+
end
|
30
|
+
|
31
|
+
def write_json_translation(attr_name, value, locale = I18n.locale)
|
32
|
+
translation_store = "#{attr_name}#{SUFFIX}"
|
33
|
+
translations = public_send(translation_store) || {}
|
34
|
+
public_send("#{translation_store}_will_change!") unless translations[locale.to_s] == value
|
35
|
+
translations[locale.to_s] = value
|
36
|
+
public_send("#{translation_store}=", translations)
|
37
|
+
value
|
38
|
+
end
|
39
|
+
|
40
|
+
def respond_to_with_translates?(symbol, include_all = false)
|
41
|
+
return true if parse_translated_attribute_accessor(symbol)
|
42
|
+
respond_to_without_translates?(symbol, include_all)
|
43
|
+
end
|
44
|
+
|
45
|
+
def method_missing_with_translates(method_name, *args)
|
46
|
+
translated_attr_name, locale, assigning = parse_translated_attribute_accessor(method_name)
|
47
|
+
|
48
|
+
return method_missing_without_translates(method_name, *args) unless translated_attr_name
|
49
|
+
|
50
|
+
if assigning
|
51
|
+
write_json_translation(translated_attr_name, args.first, locale)
|
52
|
+
else
|
53
|
+
read_json_translation(translated_attr_name, locale)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Internal: Parse a translated convenience accessor name.
|
58
|
+
#
|
59
|
+
# method_name - The accessor name.
|
60
|
+
#
|
61
|
+
# Examples
|
62
|
+
#
|
63
|
+
# parse_translated_attribute_accessor("title_en=")
|
64
|
+
# # => [:title, :en, true]
|
65
|
+
#
|
66
|
+
# parse_translated_attribute_accessor("title_fr")
|
67
|
+
# # => [:title, :fr, false]
|
68
|
+
#
|
69
|
+
# Returns the attribute name Symbol, locale Symbol, and a Boolean
|
70
|
+
# indicating whether or not the caller is attempting to assign a value.
|
71
|
+
def parse_translated_attribute_accessor(method_name)
|
72
|
+
return unless /\A(?<attribute>[a-z_]+)_(?<locale>[a-z]{2})(?<assignment>=?)\z/ =~ method_name
|
73
|
+
|
74
|
+
translated_attr_name = attribute.to_sym
|
75
|
+
return unless translated_attribute_names.include?(translated_attr_name)
|
76
|
+
|
77
|
+
locale = locale.to_sym
|
78
|
+
assigning = assignment.present?
|
79
|
+
|
80
|
+
[translated_attr_name, locale, assigning]
|
81
|
+
end
|
82
|
+
|
83
|
+
def toggle_fallback(enabled)
|
84
|
+
if block_given?
|
85
|
+
old_value = @enabled_fallback
|
86
|
+
begin
|
87
|
+
@enabled_fallback = enabled
|
88
|
+
yield
|
89
|
+
ensure
|
90
|
+
@enabled_fallback = old_value
|
91
|
+
end
|
92
|
+
else
|
93
|
+
@enabled_fallback = enabled
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -1,13 +1,23 @@
|
|
1
1
|
module JSONTranslate
|
2
2
|
module Translates
|
3
|
-
SUFFIX = "_translations"
|
3
|
+
SUFFIX = "_translations".freeze
|
4
|
+
|
4
5
|
|
5
6
|
def translates(*attrs)
|
6
7
|
include InstanceMethods
|
7
8
|
|
8
|
-
class_attribute :
|
9
|
-
|
10
|
-
self.
|
9
|
+
class_attribute :translated_attribute_names, :permitted_translated_attributes
|
10
|
+
|
11
|
+
self.translated_attribute_names = attrs
|
12
|
+
self.permitted_translated_attributes = [
|
13
|
+
*self.ancestors
|
14
|
+
.select {|klass| klass.respond_to?(:permitted_translated_attributes) }
|
15
|
+
.map(&:permitted_translated_attributes),
|
16
|
+
*attrs.product(I18n.available_locales)
|
17
|
+
.map { |attribute, locale| :"#{attribute}_#{locale}" }
|
18
|
+
].flatten.compact
|
19
|
+
|
20
|
+
puts "PermittedTranslatedAttributes #{permitted_translated_attributes}"
|
11
21
|
|
12
22
|
attrs.each do |attr_name|
|
13
23
|
define_method attr_name do
|
@@ -25,113 +35,11 @@ module JSONTranslate
|
|
25
35
|
end
|
26
36
|
end
|
27
37
|
|
28
|
-
|
29
|
-
alias_method_chain :method_missing, :translates
|
38
|
+
send(:prepend, ActiveRecordWithJSONTranslate)
|
30
39
|
end
|
31
40
|
|
32
|
-
# Improve compatibility with the gem globalize
|
33
41
|
def translates?
|
34
42
|
included_modules.include?(InstanceMethods)
|
35
43
|
end
|
36
|
-
|
37
|
-
module InstanceMethods
|
38
|
-
def disable_fallback
|
39
|
-
toggle_fallback(false)
|
40
|
-
end
|
41
|
-
|
42
|
-
def enable_fallback
|
43
|
-
toggle_fallback(true)
|
44
|
-
end
|
45
|
-
|
46
|
-
protected
|
47
|
-
|
48
|
-
def json_translate_fallback_locales(locale)
|
49
|
-
return if @enabled_fallback == false || !I18n.respond_to?(:fallbacks)
|
50
|
-
I18n.fallbacks[locale]
|
51
|
-
end
|
52
|
-
|
53
|
-
def read_json_translation(attr_name, locale = I18n.locale)
|
54
|
-
translations = send("#{attr_name}#{SUFFIX}") || {}
|
55
|
-
translation = translations[locale.to_s]
|
56
|
-
|
57
|
-
if fallback_locales = json_translate_fallback_locales(locale)
|
58
|
-
fallback_locales.each do |fallback_locale|
|
59
|
-
t = translations[fallback_locale.to_s]
|
60
|
-
if t && !t.empty? # differs from blank?
|
61
|
-
translation = t
|
62
|
-
break
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
translation
|
68
|
-
end
|
69
|
-
|
70
|
-
def write_json_translation(attr_name, value, locale = I18n.locale)
|
71
|
-
translation_store = "#{attr_name}#{SUFFIX}"
|
72
|
-
translations = send(translation_store) || {}
|
73
|
-
send("#{translation_store}_will_change!") unless translations[locale.to_s] == value
|
74
|
-
translations[locale.to_s] = value
|
75
|
-
send("#{translation_store}=", translations)
|
76
|
-
value
|
77
|
-
end
|
78
|
-
|
79
|
-
def respond_to_with_translates?(symbol, include_all = false)
|
80
|
-
return true if parse_translated_attribute_accessor(symbol)
|
81
|
-
respond_to_without_translates?(symbol, include_all)
|
82
|
-
end
|
83
|
-
|
84
|
-
def method_missing_with_translates(method_name, *args)
|
85
|
-
translated_attr_name, locale, assigning = parse_translated_attribute_accessor(method_name)
|
86
|
-
|
87
|
-
return method_missing_without_translates(method_name, *args) unless translated_attr_name
|
88
|
-
|
89
|
-
if assigning
|
90
|
-
write_json_translation(translated_attr_name, args.first, locale)
|
91
|
-
else
|
92
|
-
read_json_translation(translated_attr_name, locale)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Internal: Parse a translated convenience accessor name.
|
97
|
-
#
|
98
|
-
# method_name - The accessor name.
|
99
|
-
#
|
100
|
-
# Examples
|
101
|
-
#
|
102
|
-
# parse_translated_attribute_accessor("title_en=")
|
103
|
-
# # => [:title, :en, true]
|
104
|
-
#
|
105
|
-
# parse_translated_attribute_accessor("title_fr")
|
106
|
-
# # => [:title, :fr, false]
|
107
|
-
#
|
108
|
-
# Returns the attribute name Symbol, locale Symbol, and a Boolean
|
109
|
-
# indicating whether or not the caller is attempting to assign a value.
|
110
|
-
def parse_translated_attribute_accessor(method_name)
|
111
|
-
return unless method_name =~ /\A([a-z_]+)_([a-z]{2})(=?)\z/
|
112
|
-
|
113
|
-
translated_attr_name = $1.to_sym
|
114
|
-
return unless translated_attrs.include?(translated_attr_name)
|
115
|
-
|
116
|
-
locale = $2.to_sym
|
117
|
-
assigning = $3.present?
|
118
|
-
|
119
|
-
[translated_attr_name, locale, assigning]
|
120
|
-
end
|
121
|
-
|
122
|
-
def toggle_fallback(enabled)
|
123
|
-
if block_given?
|
124
|
-
old_value = @enabled_fallback
|
125
|
-
begin
|
126
|
-
@enabled_fallback = enabled
|
127
|
-
yield
|
128
|
-
ensure
|
129
|
-
@enabled_fallback = old_value
|
130
|
-
end
|
131
|
-
else
|
132
|
-
@enabled_fallback = enabled
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
44
|
end
|
137
45
|
end
|
data/lib/json_translate.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "active_record"
|
2
|
+
require "json_translate/translates"
|
3
|
+
require "json_translate/translates/instance_methods"
|
4
|
+
require "json_translate/translates/active_record_with_json_translates"
|
3
5
|
|
4
6
|
ActiveRecord::Base.extend(JSONTranslate::Translates)
|
data/test/test_helper.rb
CHANGED
@@ -4,12 +4,16 @@ require 'json_translate'
|
|
4
4
|
require 'database_cleaner'
|
5
5
|
DatabaseCleaner.strategy = :transaction
|
6
6
|
|
7
|
-
|
7
|
+
I18n.available_locales = [:en, :fr]
|
8
8
|
|
9
9
|
class Post < ActiveRecord::Base
|
10
10
|
translates :title
|
11
11
|
end
|
12
12
|
|
13
|
+
class PostDetailed < Post
|
14
|
+
translates :comment
|
15
|
+
end
|
16
|
+
|
13
17
|
class JSONTranslate::Test < Minitest::Test
|
14
18
|
class << self
|
15
19
|
def prepare_database
|
@@ -41,6 +45,7 @@ class JSONTranslate::Test < Minitest::Test
|
|
41
45
|
connection = establish_connection(db_config)
|
42
46
|
connection.create_table(:posts, :force => true) do |t|
|
43
47
|
t.column :title_translations, 'jsonb'
|
48
|
+
t.column :comment_translations, 'jsonb'
|
44
49
|
end
|
45
50
|
end
|
46
51
|
end
|
data/test/translates_test.rb
CHANGED
@@ -144,5 +144,28 @@ class TranslatesTest < JSONTranslate::Test
|
|
144
144
|
|
145
145
|
def test_class_method_translates?
|
146
146
|
assert_equal true, Post.translates?
|
147
|
+
assert_equal true, PostDetailed.translates?
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_translate_post_detailed
|
151
|
+
p = PostDetailed.create!(
|
152
|
+
:title_translations => {
|
153
|
+
"en" => "Alice in Wonderland",
|
154
|
+
"fr" => "Alice au pays des merveilles"
|
155
|
+
},
|
156
|
+
:comment_translations => {
|
157
|
+
"en" => "Awesome book",
|
158
|
+
"fr" => "Un livre unique"
|
159
|
+
}
|
160
|
+
)
|
161
|
+
|
162
|
+
I18n.with_locale(:en) { assert_equal "Awesome book", p.comment }
|
163
|
+
I18n.with_locale(:en) { assert_equal "Alice in Wonderland", p.title }
|
164
|
+
I18n.with_locale(:fr) { assert_equal "Un livre unique", p.comment }
|
165
|
+
I18n.with_locale(:fr) { assert_equal "Alice au pays des merveilles", p.title }
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_permitted_translated_attributes
|
169
|
+
assert_equal [:title_en, :title_fr, :comment_en, :comment_fr], PostDetailed.permitted_translated_attributes
|
147
170
|
end
|
148
171
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_translate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Worley
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-02-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: 4.2.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: 4.2.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rake
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,8 +79,11 @@ files:
|
|
79
79
|
- README.md
|
80
80
|
- lib/json_translate.rb
|
81
81
|
- lib/json_translate/translates.rb
|
82
|
+
- lib/json_translate/translates/active_record_with_json_translates.rb
|
83
|
+
- lib/json_translate/translates/instance_methods.rb
|
82
84
|
- lib/json_translate/version.rb
|
83
85
|
- test/database.yml
|
86
|
+
- test/gemfiles/Gemfile.rails-4.2.x
|
84
87
|
- test/gemfiles/Gemfile.rails-5.0.x
|
85
88
|
- test/test_helper.rb
|
86
89
|
- test/translates_test.rb
|
@@ -104,13 +107,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
107
|
version: '0'
|
105
108
|
requirements: []
|
106
109
|
rubyforge_project:
|
107
|
-
rubygems_version: 2.6.
|
110
|
+
rubygems_version: 2.6.10
|
108
111
|
signing_key:
|
109
112
|
specification_version: 4
|
110
113
|
summary: Rails I18n library for ActiveRecord model/data translation using PostgreSQL's
|
111
114
|
JSONB datatype.
|
112
115
|
test_files:
|
113
116
|
- test/database.yml
|
117
|
+
- test/gemfiles/Gemfile.rails-4.2.x
|
114
118
|
- test/gemfiles/Gemfile.rails-5.0.x
|
115
119
|
- test/test_helper.rb
|
116
120
|
- test/translates_test.rb
|