single_table_globalize3 0.0.1 → 0.0.2
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/Gemfile +1 -1
- data/Gemfile.lock +1 -12
- data/lib/generators/single_table_globalize3/migration_generator.rb +12 -0
- data/lib/generators/{globalize3 → single_table_globalize3}/templates/migration.rb +0 -0
- data/lib/i18n/missing_translations_log_handler.rb +1 -1
- data/lib/i18n/missing_translations_raise_handler.rb +1 -1
- data/lib/patches/active_record/uniqueness_validator.rb +2 -2
- data/lib/{globalize → single_table_globalize3}/active_record/act_macro.rb +9 -27
- data/lib/{globalize → single_table_globalize3}/active_record/adapter.rb +13 -12
- data/lib/single_table_globalize3/active_record/attribute_read_write.rb +75 -0
- data/lib/{globalize → single_table_globalize3}/active_record/attributes.rb +2 -2
- data/lib/{globalize → single_table_globalize3}/active_record/class_methods.rb +3 -61
- data/lib/{globalize → single_table_globalize3}/active_record/exceptions.rb +4 -4
- data/lib/{globalize → single_table_globalize3}/active_record/instance_methods.rb +6 -73
- data/lib/{globalize → single_table_globalize3}/active_record/translation.rb +7 -1
- data/lib/single_table_globalize3/active_record/with_translations.rb +59 -0
- data/lib/single_table_globalize3/active_record.rb +14 -0
- data/lib/single_table_globalize3/version.rb +1 -1
- data/lib/single_table_globalize3.rb +73 -1
- metadata +16 -16
- data/lib/generators/globalize3/migration_generator.rb +0 -14
- data/lib/globalize/active_record.rb +0 -12
- data/lib/globalize.rb +0 -74
- data/lib/patches/active_record/query_method.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26717252049728b19cb768820301e55d01b6d0d9
|
4
|
+
data.tar.gz: ddd3692c29e5a96c960150c36209df54ee1c0286
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b73332cb50bfe6a2d706a6ad4450fb471c64dc102264a2310171e12f1ee78d43dfaf59ed8fe8bc14ebddc26cbbcbea5e711b4638057c38168a06266bc90d4745
|
7
|
+
data.tar.gz: 238fbd2b8c9bb11dec4c5cc3a58a8d529f734171f896d86f1109dd66d38248b31ba36c196b35d6567253ac55d49aec26dcd1ba276245f285dfc6fa906fe33475
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
single_table_globalize3 (0.
|
4
|
+
single_table_globalize3 (0.0.1)
|
5
5
|
activemodel (>= 3.0.0)
|
6
6
|
activerecord (>= 3.0.0)
|
7
7
|
|
@@ -21,26 +21,17 @@ GEM
|
|
21
21
|
multi_json (~> 1.0)
|
22
22
|
arel (3.0.2)
|
23
23
|
builder (3.0.4)
|
24
|
-
coderay (1.0.8)
|
25
24
|
database_cleaner (0.6.7)
|
26
25
|
i18n (0.6.1)
|
27
26
|
json (1.7.7)
|
28
27
|
metaclass (0.0.1)
|
29
|
-
method_source (0.8.1)
|
30
28
|
mocha (0.13.2)
|
31
29
|
metaclass (~> 0.0.1)
|
32
30
|
multi_json (1.6.1)
|
33
31
|
pathname_local (0.0.2)
|
34
|
-
pry (0.9.12)
|
35
|
-
coderay (~> 1.0.5)
|
36
|
-
method_source (~> 0.8)
|
37
|
-
slop (~> 3.4)
|
38
|
-
pry-nav (0.2.3)
|
39
|
-
pry (~> 0.9.10)
|
40
32
|
rake (10.0.3)
|
41
33
|
rdoc (3.12.1)
|
42
34
|
json (~> 1.4)
|
43
|
-
slop (3.4.3)
|
44
35
|
sqlite3 (1.3.7)
|
45
36
|
test_declarative (0.0.5)
|
46
37
|
tzinfo (0.3.35)
|
@@ -52,8 +43,6 @@ DEPENDENCIES
|
|
52
43
|
database_cleaner (~> 0.6.0)
|
53
44
|
mocha
|
54
45
|
pathname_local
|
55
|
-
pry
|
56
|
-
pry-nav
|
57
46
|
rake
|
58
47
|
rdoc
|
59
48
|
single_table_globalize3!
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module SingleTableGlobalize3
|
4
|
+
class MigrationGenerator < ::ActiveRecord::Generators::Base
|
5
|
+
source_root File.expand_path("../templates", __FILE__)
|
6
|
+
argument :name, :type => :string, :default => "application"
|
7
|
+
|
8
|
+
def copy_devise_migration
|
9
|
+
migration_template "migration.rb", "db/migrate/create_globalize_translations"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
File without changes
|
@@ -5,7 +5,7 @@
|
|
5
5
|
#
|
6
6
|
# E.g.
|
7
7
|
#
|
8
|
-
# require '
|
8
|
+
# require 'single_table_globalize3/i18n/missing_translations_log_handler'
|
9
9
|
# I18n.missing_translations_logger = RAILS_DEFAULT_LOGGER
|
10
10
|
# I18n.exception_handler = :missing_translations_log_handler
|
11
11
|
#
|
@@ -9,7 +9,7 @@ ActiveRecord::Validations::UniquenessValidator.class_eval do
|
|
9
9
|
table = finder_class.arel_table
|
10
10
|
|
11
11
|
relation = build_relation(finder_class, table, 'attribute_name', attribute).
|
12
|
-
and(table[:locale].eq(
|
12
|
+
and(table[:locale].eq(SingleTableGlobalize3.locale)).
|
13
13
|
and(table[:value].eq(value)).
|
14
14
|
and(table[:translatable_type].eq(klass.name))
|
15
15
|
relation = relation.and(table[klass.reflect_on_association(:translations).foreign_key].not_eq(record.send(:id))) if record.persisted?
|
@@ -35,7 +35,7 @@ ActiveRecord::Validations::UniquenessValidator.class_eval do
|
|
35
35
|
sql, params = mount_sql_and_params(finder_class, table_name, 'value', value)
|
36
36
|
|
37
37
|
relation = table.where(sql, *params).
|
38
|
-
where(:locale =>
|
38
|
+
where(:locale => SingleTableGlobalize3.locale).
|
39
39
|
where(:attribute_name => attribute).
|
40
40
|
where(:translatable_type => klass.name)
|
41
41
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module SingleTableGlobalize3
|
2
2
|
module ActiveRecord
|
3
3
|
module ActMacro
|
4
4
|
def translates(*attr_names)
|
@@ -9,31 +9,13 @@ module Globalize
|
|
9
9
|
attr_names = attr_names.map(&:to_sym)
|
10
10
|
attr_names -= translated_attribute_names if defined?(translated_attribute_names)
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
attr_names.each do |attr_name|
|
13
|
+
# Create accessors for the attribute.
|
14
|
+
translated_attr_accessor(attr_name)
|
15
|
+
translations_accessor(attr_name)
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
serializer = self.serialized_attributes[attr_name.to_s]
|
20
|
-
if serializer.present?
|
21
|
-
if defined?(::ActiveRecord::Coders::YAMLColumn) &&
|
22
|
-
serializer.is_a?(::ActiveRecord::Coders::YAMLColumn)
|
23
|
-
|
24
|
-
serializer = serializer.object_class
|
25
|
-
end
|
26
|
-
|
27
|
-
translation_class.send :serialize, attr_name, serializer
|
28
|
-
end
|
29
|
-
|
30
|
-
# Create accessors for the attribute.
|
31
|
-
translated_attr_accessor(attr_name)
|
32
|
-
translations_accessor(attr_name)
|
33
|
-
|
34
|
-
# Add attribute to the list.
|
35
|
-
self.translated_attribute_names << attr_name
|
36
|
-
end
|
17
|
+
# Add attribute to the list.
|
18
|
+
self.translated_attribute_names << attr_name
|
37
19
|
end
|
38
20
|
end
|
39
21
|
|
@@ -58,8 +40,8 @@ module Globalize
|
|
58
40
|
|
59
41
|
after_create :save_translations!
|
60
42
|
after_update :save_translations!
|
61
|
-
|
62
|
-
|
43
|
+
# if attr_accessible is explicitly defined in the class, add locale to it
|
44
|
+
attr_accessible :locale if self.accessible_attributes.to_a.present?
|
63
45
|
end
|
64
46
|
end
|
65
47
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module SingleTableGlobalize3
|
2
2
|
module ActiveRecord
|
3
3
|
class Adapter
|
4
4
|
# The cache caches attributes that already were looked up for read access.
|
@@ -14,9 +14,17 @@ module Globalize
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def fetch_stash(locale, name)
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
stash.read(locale, name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def fetch_locales(name)
|
21
|
+
stash.keys.inject({}) do |result, locale|
|
22
|
+
if stash_contains?(locale, name)
|
23
|
+
result.update(locale => fetch_stash(locale, name))
|
24
|
+
else
|
25
|
+
result
|
26
|
+
end
|
27
|
+
end
|
20
28
|
end
|
21
29
|
|
22
30
|
def stash_contains?(locale, name)
|
@@ -41,17 +49,10 @@ module Globalize
|
|
41
49
|
end
|
42
50
|
|
43
51
|
def save_translations!
|
44
|
-
existing_translations = {}
|
45
|
-
record.translations.each do |t|
|
46
|
-
locale_str = t.locale.to_s
|
47
|
-
existing_translations[locale_str] ||= {}
|
48
|
-
existing_translations[locale_str][t.attribute_name] = t
|
49
|
-
end
|
50
|
-
|
51
52
|
stash.each do |locale, attrs|
|
52
53
|
locale_str = locale.to_s
|
53
54
|
attrs.each do |name, value|
|
54
|
-
translation =
|
55
|
+
translation = record.translations.detect {|t| t.locale.to_s == locale_str && t.attribute_name == name } ||
|
55
56
|
record.translations.build(:locale => locale_str, :attribute_name => name)
|
56
57
|
translation.update_attribute(:value, value)
|
57
58
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module SingleTableGlobalize3
|
2
|
+
module ActiveRecord
|
3
|
+
module AttributeReadWrite
|
4
|
+
delegate :translated_locales, :to => :translations
|
5
|
+
def attributes
|
6
|
+
super.merge(translated_attributes)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Deprecate old use of locale
|
10
|
+
def deprecated_options(options)
|
11
|
+
unless options.is_a?(Hash)
|
12
|
+
warn "[DEPRECATION] passing 'locale' as #{options.inspect} is deprecated. Please use {:locale => #{options.inspect}} instead."
|
13
|
+
{:locale => options}
|
14
|
+
else
|
15
|
+
options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def write_attribute(name, value, options = {})
|
20
|
+
if translated?(name)
|
21
|
+
options = {:locale => SingleTableGlobalize3.locale}.merge(deprecated_options(options))
|
22
|
+
|
23
|
+
# Dirty tracking, paraphrased from
|
24
|
+
# ActiveRecord::AttributeMethods::Dirty#write_attribute.
|
25
|
+
name_str = name.to_s
|
26
|
+
# If there's already a change, delete it if this undoes the change.
|
27
|
+
if attribute_changed?(name_str) && value == changed_attributes[name_str]
|
28
|
+
changed_attributes.delete(name_str)
|
29
|
+
elsif !attribute_changed?(name_str) && value != (old = globalize.fetch(options[:locale], name))
|
30
|
+
changed_attributes[name_str] = old
|
31
|
+
end
|
32
|
+
|
33
|
+
globalize.write(options[:locale], name, value)
|
34
|
+
else
|
35
|
+
super(name, value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def read_attribute(name, options = {})
|
40
|
+
options = {:translated => true, :locale => nil}.merge(deprecated_options(options))
|
41
|
+
if (self.class.translated?(name) && options[:translated]) && (value = globalize.fetch(options[:locale] || SingleTableGlobalize3.locale, name))
|
42
|
+
value
|
43
|
+
else
|
44
|
+
super(name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def attribute_names
|
49
|
+
translated_attribute_names.map(&:to_s) + super
|
50
|
+
end
|
51
|
+
|
52
|
+
def translated?(name)
|
53
|
+
self.class.translated?(name)
|
54
|
+
end
|
55
|
+
|
56
|
+
def translated_attributes
|
57
|
+
translated_attribute_names.inject({}) do |attributes, name|
|
58
|
+
attributes.merge(name.to_s => translation[name.to_s].try(:value))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# This method is basically the method built into Rails
|
63
|
+
# but we have to pass {:translated => false}
|
64
|
+
def untranslated_attributes
|
65
|
+
attrs = {}
|
66
|
+
attribute_names.each do |name|
|
67
|
+
attrs[name] = read_attribute(name, {:translated => false})
|
68
|
+
end
|
69
|
+
attrs
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
# Helper class for storing values per locale. Used by
|
1
|
+
# Helper class for storing values per locale. Used by SingleTableGlobalize3::Adapter
|
2
2
|
# to stash and cache attribute values.
|
3
3
|
|
4
|
-
module
|
4
|
+
module SingleTableGlobalize3
|
5
5
|
module ActiveRecord
|
6
6
|
class Attributes < Hash # TODO: Think about using HashWithIndifferentAccess ?
|
7
7
|
def [](locale)
|
@@ -1,49 +1,7 @@
|
|
1
|
-
module
|
1
|
+
module SingleTableGlobalize3
|
2
2
|
module ActiveRecord
|
3
3
|
module ClassMethods
|
4
|
-
|
5
|
-
|
6
|
-
def with_translations(*locales)
|
7
|
-
locales = [locales].flatten
|
8
|
-
index = locales.pop if locales.last.is_a?(Fixnum)
|
9
|
-
locales = Globalize.fallbacks if locales.empty?
|
10
|
-
joins("LEFT OUTER JOIN #{translation_class.table_name} #{translations_table_name(index)} ON #{translations_table_name(index)}.translatable_id = #{self.table_name}.id").
|
11
|
-
select("distinct #{table_name}.*").
|
12
|
-
where(translated_column_name('locale', index) => locales)
|
13
|
-
end
|
14
|
-
|
15
|
-
def with_translated_attribute(name, value, locales = nil)
|
16
|
-
locales ||= Globalize.fallbacks
|
17
|
-
self.join_index = self.join_index + 1
|
18
|
-
with_translations(locales, self.join_index).where(
|
19
|
-
translated_column_name('attribute_name', self.join_index) => name.to_s,
|
20
|
-
translated_column_name('value', self.join_index) => Array(value).map(&:to_s)
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
def translated?(name)
|
25
|
-
translated_attribute_names.include?(name.to_sym)
|
26
|
-
end
|
27
|
-
|
28
|
-
def required_attributes
|
29
|
-
validators.map { |v| v.attributes if v.is_a?(ActiveModel::Validations::PresenceValidator) }.flatten
|
30
|
-
end
|
31
|
-
|
32
|
-
def required_translated_attributes
|
33
|
-
translated_attribute_names & required_attributes
|
34
|
-
end
|
35
|
-
|
36
|
-
def translation_class
|
37
|
-
Globalize::ActiveRecord::Translation
|
38
|
-
end
|
39
|
-
|
40
|
-
def translations_table_name(index = nil)
|
41
|
-
"#{translation_class.table_name}#{index}"
|
42
|
-
end
|
43
|
-
|
44
|
-
def translated_column_name(name, index = nil)
|
45
|
-
"#{translations_table_name(index)}.#{name}"
|
46
|
-
end
|
4
|
+
include WithTranslations
|
47
5
|
|
48
6
|
if RUBY_VERSION < '1.9'
|
49
7
|
def respond_to?(method_id, *args, &block)
|
@@ -139,12 +97,7 @@ module Globalize
|
|
139
97
|
|
140
98
|
def translations_accessor(name)
|
141
99
|
define_method(:"#{name}_translations") do
|
142
|
-
|
143
|
-
result[translation.locale] = translation.value
|
144
|
-
end
|
145
|
-
globalize.stash.keys.each_with_object(result) do |locale, result|
|
146
|
-
result[locale] = globalize.fetch_stash(locale, name) if globalize.stash_contains?(locale, name)
|
147
|
-
end
|
100
|
+
translations.attribute_translations(name).merge(globalize.fetch_locales(name))
|
148
101
|
end
|
149
102
|
define_method(:"#{name}_translations=") do |value|
|
150
103
|
value.each do |(locale, value)|
|
@@ -152,17 +105,6 @@ module Globalize
|
|
152
105
|
end
|
153
106
|
end
|
154
107
|
end
|
155
|
-
|
156
|
-
def join_index
|
157
|
-
@join_index = 0 if @join_index.nil? || @join_index > 100
|
158
|
-
@join_index
|
159
|
-
end
|
160
|
-
|
161
|
-
def join_index=(value)
|
162
|
-
@join_index = value
|
163
|
-
end
|
164
108
|
end
|
165
|
-
|
166
109
|
end
|
167
|
-
|
168
110
|
end
|
@@ -1,14 +1,14 @@
|
|
1
|
-
module
|
1
|
+
module SingleTableGlobalize3
|
2
2
|
module ActiveRecord
|
3
3
|
module Exceptions
|
4
4
|
class MigrationError < StandardError; end
|
5
|
-
|
5
|
+
|
6
6
|
class BadFieldName < MigrationError
|
7
7
|
def initialize(field)
|
8
8
|
super("Missing translated field #{field.inspect}")
|
9
9
|
end
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
class BadFieldType < MigrationError
|
13
13
|
def initialize(name, type)
|
14
14
|
super("Bad field type for field #{name.inspect} (#{type.inspect}), should be :string or :text")
|
@@ -16,4 +16,4 @@ module Globalize
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
19
|
-
end
|
19
|
+
end
|
@@ -1,16 +1,12 @@
|
|
1
|
-
module
|
1
|
+
module SingleTableGlobalize3
|
2
2
|
module ActiveRecord
|
3
3
|
module InstanceMethods
|
4
|
-
|
4
|
+
include AttributeReadWrite
|
5
5
|
|
6
6
|
def globalize
|
7
7
|
@globalize ||= Adapter.new(self)
|
8
8
|
end
|
9
9
|
|
10
|
-
def attributes
|
11
|
-
super.merge(translated_attributes)
|
12
|
-
end
|
13
|
-
|
14
10
|
def self.included(base)
|
15
11
|
# Maintain Rails 3.0.x compatibility while adding Rails 3.1.x compatibility
|
16
12
|
if base.method_defined?(:assign_attributes)
|
@@ -36,76 +32,13 @@ module Globalize
|
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|
39
|
-
# Deprecate old use of locale
|
40
|
-
def deprecated_options(options)
|
41
|
-
unless options.is_a?(Hash)
|
42
|
-
warn "[DEPRECATION] passing 'locale' as #{options.inspect} is deprecated. Please use {:locale => #{options.inspect}} instead."
|
43
|
-
{:locale => options}
|
44
|
-
else
|
45
|
-
options
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def write_attribute(name, value, options = {})
|
50
|
-
if translated?(name)
|
51
|
-
options = {:locale => Globalize.locale}.merge(deprecated_options(options))
|
52
|
-
|
53
|
-
# Dirty tracking, paraphrased from
|
54
|
-
# ActiveRecord::AttributeMethods::Dirty#write_attribute.
|
55
|
-
name_str = name.to_s
|
56
|
-
# If there's already a change, delete it if this undoes the change.
|
57
|
-
if attribute_changed?(name_str) && value == changed_attributes[name_str]
|
58
|
-
changed_attributes.delete(name_str)
|
59
|
-
elsif !attribute_changed?(name_str) && value != (old = globalize.fetch(options[:locale], name))
|
60
|
-
changed_attributes[name_str] = old
|
61
|
-
end
|
62
|
-
|
63
|
-
globalize.write(options[:locale], name, value)
|
64
|
-
else
|
65
|
-
super(name, value)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def read_attribute(name, options = {})
|
70
|
-
options = {:translated => true, :locale => nil}.merge(deprecated_options(options))
|
71
|
-
if (self.class.translated?(name) && options[:translated]) && (value = globalize.fetch(options[:locale] || Globalize.locale, name))
|
72
|
-
value
|
73
|
-
else
|
74
|
-
super(name)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def attribute_names
|
79
|
-
translated_attribute_names.map(&:to_s) + super
|
80
|
-
end
|
81
|
-
|
82
|
-
def translated?(name)
|
83
|
-
self.class.translated?(name)
|
84
|
-
end
|
85
|
-
|
86
|
-
def translated_attributes
|
87
|
-
translated_attribute_names.inject({}) do |attributes, name|
|
88
|
-
attributes.merge(name.to_s => translation[name.to_s].try(:value))
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# This method is basically the method built into Rails
|
93
|
-
# but we have to pass {:translated => false}
|
94
|
-
def untranslated_attributes
|
95
|
-
attrs = {}
|
96
|
-
attribute_names.each do |name|
|
97
|
-
attrs[name] = read_attribute(name, {:translated => false})
|
98
|
-
end
|
99
|
-
attrs
|
100
|
-
end
|
101
|
-
|
102
35
|
def set_translations(options)
|
103
36
|
options.keys.each do |locale|
|
104
37
|
options[locale].each do |key, value|
|
105
38
|
raise NoMethodError.new("unknown attribute: #{key}") unless attribute_names.flatten.include?(key.to_s)
|
106
39
|
translation = translation_for(locale, key.to_s)
|
107
40
|
translation.value = value
|
108
|
-
translation.save
|
41
|
+
translation.save!
|
109
42
|
end
|
110
43
|
end
|
111
44
|
globalize.reset
|
@@ -132,7 +65,7 @@ module Globalize
|
|
132
65
|
end
|
133
66
|
|
134
67
|
def translation
|
135
|
-
translations_for_locale(::
|
68
|
+
translations_for_locale(::SingleTableGlobalize3.locale)
|
136
69
|
end
|
137
70
|
|
138
71
|
def translation_for(locale, name, build_if_missing = true)
|
@@ -157,7 +90,7 @@ module Globalize
|
|
157
90
|
end
|
158
91
|
|
159
92
|
def globalize_fallbacks(locale)
|
160
|
-
|
93
|
+
SingleTableGlobalize3.fallbacks(locale)
|
161
94
|
end
|
162
95
|
|
163
96
|
private
|
@@ -200,7 +133,7 @@ module Globalize
|
|
200
133
|
attributes.try(:delete, :locale)
|
201
134
|
|
202
135
|
if locale
|
203
|
-
|
136
|
+
SingleTableGlobalize3.with_locale(locale, &block)
|
204
137
|
else
|
205
138
|
yield
|
206
139
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module SingleTableGlobalize3
|
2
2
|
module ActiveRecord
|
3
3
|
class Translation < ::ActiveRecord::Base
|
4
4
|
if self.respond_to?(:table_name=)
|
@@ -28,6 +28,12 @@ module Globalize
|
|
28
28
|
attribute = attribute.to_s
|
29
29
|
where :attribute_name => attribute
|
30
30
|
end
|
31
|
+
|
32
|
+
def attribute_translations(attribute)
|
33
|
+
attribute(attribute).inject(HashWithIndifferentAccess.new) do |hash, translation|
|
34
|
+
hash.update(translation.locale => translation.value)
|
35
|
+
end
|
36
|
+
end
|
31
37
|
end
|
32
38
|
|
33
39
|
def locale
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module SingleTableGlobalize3
|
2
|
+
module ActiveRecord
|
3
|
+
module WithTranslations
|
4
|
+
delegate :translated_locales, :to => :translation_class
|
5
|
+
|
6
|
+
def with_translations(*locales)
|
7
|
+
index = locales.pop if locales.last.is_a?(Fixnum)
|
8
|
+
locales = locales.concat(SingleTableGlobalize3.fallbacks).flatten.map(&:to_s)
|
9
|
+
alias_table_name = translations_table_name(index)
|
10
|
+
|
11
|
+
joins("LEFT OUTER JOIN #{translation_class.table_name} #{alias_table_name} ON #{alias_table_name}.translatable_id = #{table_name}.id").
|
12
|
+
select("distinct #{table_name}.*").
|
13
|
+
where(translated_column_name('locale', index) => locales)
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_translated_attribute(name, value, locales = nil)
|
17
|
+
locales ||= SingleTableGlobalize3.fallbacks
|
18
|
+
self.join_index = self.join_index + 1
|
19
|
+
with_translations(locales, self.join_index).where(
|
20
|
+
translated_column_name('attribute_name', self.join_index) => name.to_s,
|
21
|
+
translated_column_name('value', self.join_index) => Array(value).map(&:to_s)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def translated?(name)
|
26
|
+
translated_attribute_names.include?(name.to_sym)
|
27
|
+
end
|
28
|
+
|
29
|
+
def required_attributes
|
30
|
+
validators.map { |v| v.attributes if v.is_a?(ActiveModel::Validations::PresenceValidator) }.flatten
|
31
|
+
end
|
32
|
+
|
33
|
+
def required_translated_attributes
|
34
|
+
translated_attribute_names & required_attributes
|
35
|
+
end
|
36
|
+
|
37
|
+
def translation_class
|
38
|
+
SingleTableGlobalize3::ActiveRecord::Translation
|
39
|
+
end
|
40
|
+
|
41
|
+
def translations_table_name(index = nil)
|
42
|
+
"#{translation_class.table_name}#{index}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def translated_column_name(name, index = nil)
|
46
|
+
"#{translations_table_name(index)}.#{name}"
|
47
|
+
end
|
48
|
+
protected
|
49
|
+
def join_index
|
50
|
+
@join_index = 0 if @join_index.nil? || @join_index > 100
|
51
|
+
@join_index
|
52
|
+
end
|
53
|
+
|
54
|
+
def join_index=(value)
|
55
|
+
@join_index = value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SingleTableGlobalize3
|
2
|
+
module ActiveRecord
|
3
|
+
autoload :ActMacro, 'single_table_globalize3/active_record/act_macro'
|
4
|
+
autoload :Adapter, 'single_table_globalize3/active_record/adapter'
|
5
|
+
autoload :AttributeReadWrite, 'single_table_globalize3/active_record/attribute_read_write'
|
6
|
+
autoload :Attributes, 'single_table_globalize3/active_record/attributes'
|
7
|
+
autoload :ClassMethods, 'single_table_globalize3/active_record/class_methods'
|
8
|
+
autoload :WithTranslations, 'single_table_globalize3/active_record/with_translations'
|
9
|
+
autoload :Exceptions, 'single_table_globalize3/active_record/exceptions'
|
10
|
+
autoload :InstanceMethods, 'single_table_globalize3/active_record/instance_methods'
|
11
|
+
autoload :Migration, 'single_table_globalize3/active_record/migration'
|
12
|
+
autoload :Translation, 'single_table_globalize3/active_record/translation'
|
13
|
+
end
|
14
|
+
end
|
@@ -1 +1,73 @@
|
|
1
|
-
require '
|
1
|
+
require 'active_record'
|
2
|
+
require 'patches/active_record/xml_attribute_serializer'
|
3
|
+
require 'patches/active_record/uniqueness_validator'
|
4
|
+
|
5
|
+
module SingleTableGlobalize3
|
6
|
+
autoload :ActiveRecord, 'single_table_globalize3/active_record'
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def locale
|
10
|
+
read_locale || I18n.locale
|
11
|
+
end
|
12
|
+
|
13
|
+
def locale=(locale)
|
14
|
+
set_locale(locale)
|
15
|
+
end
|
16
|
+
|
17
|
+
def with_locale(locale, &block)
|
18
|
+
previous_locale = read_locale
|
19
|
+
set_locale(locale)
|
20
|
+
result = yield(locale)
|
21
|
+
set_locale(previous_locale)
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
def with_locales(*locales, &block)
|
26
|
+
locales.flatten.map do |locale|
|
27
|
+
with_locale(locale, &block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def fallbacks=(locales)
|
32
|
+
set_fallbacks(locales)
|
33
|
+
end
|
34
|
+
|
35
|
+
def i18n_fallbacks?
|
36
|
+
I18n.respond_to?(:fallbacks)
|
37
|
+
end
|
38
|
+
|
39
|
+
def fallbacks(for_locale = self.locale)
|
40
|
+
read_fallbacks[for_locale] || default_fallbacks(for_locale)
|
41
|
+
end
|
42
|
+
|
43
|
+
def default_fallbacks(for_locale = self.locale)
|
44
|
+
i18n_fallbacks? ? I18n.fallbacks[for_locale] : [for_locale.to_sym]
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def read_locale
|
50
|
+
Thread.current[:globalize_locale]
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_locale(locale)
|
54
|
+
Thread.current[:globalize_locale] = locale.try(:to_sym)
|
55
|
+
end
|
56
|
+
|
57
|
+
def read_fallbacks
|
58
|
+
Thread.current[:fallbacks] || HashWithIndifferentAccess.new
|
59
|
+
end
|
60
|
+
|
61
|
+
def set_fallbacks(locales)
|
62
|
+
fallback_hash = HashWithIndifferentAccess.new
|
63
|
+
|
64
|
+
locales.each do |key, value|
|
65
|
+
fallback_hash[key] = value.presence || [key]
|
66
|
+
end if locales.present?
|
67
|
+
|
68
|
+
Thread.current[:fallbacks] = fallback_hash
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
ActiveRecord::Base.extend(SingleTableGlobalize3::ActiveRecord::ActMacro)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: single_table_globalize3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Fuchs
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2013-03-
|
17
|
+
date: 2013-03-13 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activerecord
|
@@ -143,28 +143,28 @@ dependencies:
|
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: '0'
|
145
145
|
description: Rails I18n de-facto standard library for ActiveRecord 3 model/data translation
|
146
|
-
with single table.
|
146
|
+
with a single table.
|
147
147
|
email: trong.v.tran@gmail.com
|
148
148
|
executables: []
|
149
149
|
extensions: []
|
150
150
|
extra_rdoc_files: []
|
151
151
|
files:
|
152
|
-
- lib/generators/
|
153
|
-
- lib/generators/
|
154
|
-
- lib/globalize/active_record/act_macro.rb
|
155
|
-
- lib/globalize/active_record/adapter.rb
|
156
|
-
- lib/globalize/active_record/attributes.rb
|
157
|
-
- lib/globalize/active_record/class_methods.rb
|
158
|
-
- lib/globalize/active_record/exceptions.rb
|
159
|
-
- lib/globalize/active_record/instance_methods.rb
|
160
|
-
- lib/globalize/active_record/translation.rb
|
161
|
-
- lib/globalize/active_record.rb
|
162
|
-
- lib/globalize.rb
|
152
|
+
- lib/generators/single_table_globalize3/migration_generator.rb
|
153
|
+
- lib/generators/single_table_globalize3/templates/migration.rb
|
163
154
|
- lib/i18n/missing_translations_log_handler.rb
|
164
155
|
- lib/i18n/missing_translations_raise_handler.rb
|
165
|
-
- lib/patches/active_record/query_method.rb
|
166
156
|
- lib/patches/active_record/uniqueness_validator.rb
|
167
157
|
- lib/patches/active_record/xml_attribute_serializer.rb
|
158
|
+
- lib/single_table_globalize3/active_record/act_macro.rb
|
159
|
+
- lib/single_table_globalize3/active_record/adapter.rb
|
160
|
+
- lib/single_table_globalize3/active_record/attribute_read_write.rb
|
161
|
+
- lib/single_table_globalize3/active_record/attributes.rb
|
162
|
+
- lib/single_table_globalize3/active_record/class_methods.rb
|
163
|
+
- lib/single_table_globalize3/active_record/exceptions.rb
|
164
|
+
- lib/single_table_globalize3/active_record/instance_methods.rb
|
165
|
+
- lib/single_table_globalize3/active_record/translation.rb
|
166
|
+
- lib/single_table_globalize3/active_record/with_translations.rb
|
167
|
+
- lib/single_table_globalize3/active_record.rb
|
168
168
|
- lib/single_table_globalize3/version.rb
|
169
169
|
- lib/single_table_globalize3.rb
|
170
170
|
- Gemfile
|
@@ -194,5 +194,5 @@ rubygems_version: 2.0.0
|
|
194
194
|
signing_key:
|
195
195
|
specification_version: 4
|
196
196
|
summary: Rails I18n de-facto standard library for ActiveRecord 3 model/data translation
|
197
|
-
with single table
|
197
|
+
with a single table
|
198
198
|
test_files: []
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'rails/generators/active_record'
|
2
|
-
|
3
|
-
module SingleTableGlobalize3
|
4
|
-
module Generators
|
5
|
-
class MigrationGenerator < ActiveRecord::Generators::Base
|
6
|
-
source_root File.expand_path("../templates", __FILE__)
|
7
|
-
argument :name, :type => :string, :default => "application"
|
8
|
-
|
9
|
-
def copy_devise_migration
|
10
|
-
migration_template "migration.rb", "db/migrate/create_globalize_translations"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
module Globalize
|
2
|
-
module ActiveRecord
|
3
|
-
autoload :ActMacro, 'globalize/active_record/act_macro'
|
4
|
-
autoload :Adapter, 'globalize/active_record/adapter'
|
5
|
-
autoload :Attributes, 'globalize/active_record/attributes'
|
6
|
-
autoload :ClassMethods, 'globalize/active_record/class_methods'
|
7
|
-
autoload :Exceptions, 'globalize/active_record/exceptions'
|
8
|
-
autoload :InstanceMethods, 'globalize/active_record/instance_methods'
|
9
|
-
autoload :Migration, 'globalize/active_record/migration'
|
10
|
-
autoload :Translation, 'globalize/active_record/translation'
|
11
|
-
end
|
12
|
-
end
|
data/lib/globalize.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
require 'patches/active_record/xml_attribute_serializer'
|
3
|
-
require 'patches/active_record/query_method'
|
4
|
-
require 'patches/active_record/uniqueness_validator'
|
5
|
-
|
6
|
-
module Globalize
|
7
|
-
autoload :ActiveRecord, 'globalize/active_record'
|
8
|
-
|
9
|
-
class << self
|
10
|
-
def locale
|
11
|
-
read_locale || I18n.locale
|
12
|
-
end
|
13
|
-
|
14
|
-
def locale=(locale)
|
15
|
-
set_locale(locale)
|
16
|
-
end
|
17
|
-
|
18
|
-
def with_locale(locale, &block)
|
19
|
-
previous_locale = read_locale
|
20
|
-
set_locale(locale)
|
21
|
-
result = yield(locale)
|
22
|
-
set_locale(previous_locale)
|
23
|
-
result
|
24
|
-
end
|
25
|
-
|
26
|
-
def with_locales(*locales, &block)
|
27
|
-
locales.flatten.map do |locale|
|
28
|
-
with_locale(locale, &block)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def fallbacks=(locales)
|
33
|
-
set_fallbacks(locales)
|
34
|
-
end
|
35
|
-
|
36
|
-
def i18n_fallbacks?
|
37
|
-
I18n.respond_to?(:fallbacks)
|
38
|
-
end
|
39
|
-
|
40
|
-
def fallbacks(for_locale = self.locale)
|
41
|
-
read_fallbacks[for_locale] || default_fallbacks(for_locale)
|
42
|
-
end
|
43
|
-
|
44
|
-
def default_fallbacks(for_locale = self.locale)
|
45
|
-
i18n_fallbacks? ? I18n.fallbacks[for_locale] : [for_locale.to_sym]
|
46
|
-
end
|
47
|
-
|
48
|
-
protected
|
49
|
-
|
50
|
-
def read_locale
|
51
|
-
Thread.current[:globalize_locale]
|
52
|
-
end
|
53
|
-
|
54
|
-
def set_locale(locale)
|
55
|
-
Thread.current[:globalize_locale] = locale.try(:to_sym)
|
56
|
-
end
|
57
|
-
|
58
|
-
def read_fallbacks
|
59
|
-
Thread.current[:fallbacks] || HashWithIndifferentAccess.new
|
60
|
-
end
|
61
|
-
|
62
|
-
def set_fallbacks(locales)
|
63
|
-
fallback_hash = HashWithIndifferentAccess.new
|
64
|
-
|
65
|
-
locales.each do |key, value|
|
66
|
-
fallback_hash[key] = value.presence || [key]
|
67
|
-
end if locales.present?
|
68
|
-
|
69
|
-
Thread.current[:fallbacks] = fallback_hash
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
ActiveRecord::Base.extend(Globalize::ActiveRecord::ActMacro)
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'active_record/attribute_methods/query'
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
module AttributeMethods
|
5
|
-
module Query
|
6
|
-
def query_attribute(attr_name)
|
7
|
-
unless value = read_attribute(attr_name)
|
8
|
-
false
|
9
|
-
else
|
10
|
-
column = self.class.columns_hash[attr_name]
|
11
|
-
if column.nil?
|
12
|
-
|
13
|
-
# TODO submit a rails patch
|
14
|
-
|
15
|
-
# not sure what active_record tests say but i guess this should mean:
|
16
|
-
# call to_i and check zero? if the value is a Numeric or starts with
|
17
|
-
# a digit, so it can meaningfully be typecasted by to_i
|
18
|
-
|
19
|
-
# if Numeric === value || value !~ /[^0-9]/
|
20
|
-
if Numeric === value || value.to_s =~ /^[0-9]/
|
21
|
-
!value.to_i.zero?
|
22
|
-
else
|
23
|
-
return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
|
24
|
-
!value.blank?
|
25
|
-
end
|
26
|
-
elsif column.number?
|
27
|
-
!value.zero?
|
28
|
-
else
|
29
|
-
!value.blank?
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|