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.
- data/README.textile +5 -0
- data/lib/globalize.rb +17 -1
- data/lib/globalize/active_record.rb +1 -41
- data/lib/globalize/active_record/act_macro.rb +18 -24
- data/lib/globalize/active_record/adapter.rb +3 -6
- data/lib/globalize/active_record/attributes.rb +1 -0
- data/lib/globalize/active_record/class_methods.rb +47 -34
- data/lib/globalize/active_record/instance_methods.rb +7 -17
- data/lib/globalize/active_record/migration.rb +5 -5
- data/lib/globalize/active_record/translation.rb +24 -0
- data/lib/globalize/version.rb +1 -1
- metadata +5 -4
data/README.textile
CHANGED
@@ -58,6 +58,11 @@ end
|
|
58
58
|
|
59
59
|
Note that the ActiveRecord model @Post@ must already exist and have a @translates@ directive listing the translated fields.
|
60
60
|
|
61
|
+
h2. Changes since Globalize2
|
62
|
+
|
63
|
+
* `translation_table_name` was renamed to `translations_table_name`
|
64
|
+
* `available_locales` has been removed. please use `translated_locales`
|
65
|
+
|
61
66
|
h2. Migration from Globalize for Rails (version 1)
|
62
67
|
|
63
68
|
See this script by Tomasz Stachewicz: http://gist.github.com/120867
|
data/lib/globalize.rb
CHANGED
@@ -4,11 +4,27 @@ module Globalize
|
|
4
4
|
autoload :ActiveRecord, 'globalize/active_record'
|
5
5
|
|
6
6
|
class << self
|
7
|
+
def locale
|
8
|
+
defined?(@@locale) && @@locale || I18n.locale
|
9
|
+
end
|
10
|
+
|
11
|
+
def locale=(locale)
|
12
|
+
@@locale = locale
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_locale(locale, &block)
|
16
|
+
previous_locale = defined?(@@locale) && @@locale || nil
|
17
|
+
self.locale = locale
|
18
|
+
result = yield
|
19
|
+
self.locale = previous_locale
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
7
23
|
def fallbacks?
|
8
24
|
I18n.respond_to?(:fallbacks)
|
9
25
|
end
|
10
26
|
|
11
|
-
def fallbacks(locale)
|
27
|
+
def fallbacks(locale = self.locale)
|
12
28
|
fallbacks? ? I18n.fallbacks[locale] : [locale.to_sym]
|
13
29
|
end
|
14
30
|
end
|
@@ -10,46 +10,6 @@ module Globalize
|
|
10
10
|
autoload :ClassMethods, 'globalize/active_record/class_methods'
|
11
11
|
autoload :InstanceMethods, 'globalize/active_record/instance_methods'
|
12
12
|
autoload :Migration, 'globalize/active_record/migration'
|
13
|
-
|
14
|
-
class << self
|
15
|
-
def build_translation_class(target, options)
|
16
|
-
options[:table_name] ||= "#{target.table_name.singularize}_translations"
|
17
|
-
|
18
|
-
klass = target.const_defined?(:Translation) ?
|
19
|
-
target.const_get(:Translation) :
|
20
|
-
target.const_set(:Translation, Class.new(::ActiveRecord::Base))
|
21
|
-
|
22
|
-
klass.class_eval do
|
23
|
-
set_table_name(options[:table_name])
|
24
|
-
|
25
|
-
belongs_to target.name.underscore.gsub('/', '_')
|
26
|
-
|
27
|
-
class << self
|
28
|
-
def by_locale(locale)
|
29
|
-
where(:locale => locale.to_s)
|
30
|
-
end
|
31
|
-
|
32
|
-
def by_locales(locales)
|
33
|
-
where(:locale => locales.map(&:to_s))
|
34
|
-
end
|
35
|
-
|
36
|
-
# TODO build is not defined here even when called through record.translations.find_or_initialize_by_locale(...)
|
37
|
-
# def find_or_initialize_by_locale(locale)
|
38
|
-
# by_locale(locale.to_s).first || build(:locale => locale.to_s)
|
39
|
-
# end
|
40
|
-
end
|
41
|
-
|
42
|
-
def locale
|
43
|
-
read_attribute(:locale).to_sym
|
44
|
-
end
|
45
|
-
|
46
|
-
def locale=(locale)
|
47
|
-
write_attribute(:locale, locale.to_s)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
klass
|
52
|
-
end
|
53
|
-
end
|
13
|
+
autoload :Translation, 'globalize/active_record/translation'
|
54
14
|
end
|
55
15
|
end
|
@@ -1,43 +1,31 @@
|
|
1
1
|
module Globalize
|
2
2
|
module ActiveRecord
|
3
3
|
module ActMacro
|
4
|
-
def locale
|
5
|
-
(defined?(@@locale) && @@locale)
|
6
|
-
end
|
7
|
-
|
8
|
-
def locale=(locale)
|
9
|
-
@@locale = locale
|
10
|
-
end
|
11
|
-
|
12
4
|
def translates(*attr_names)
|
13
5
|
return if translates?
|
14
|
-
options = attr_names.extract_options!
|
15
6
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
self.translation_class = ActiveRecord.build_translation_class(self, options)
|
20
|
-
self.translated_attribute_names = attr_names.map(&:to_sym)
|
7
|
+
options = attr_names.extract_options!
|
8
|
+
options[:table_name] ||= "#{table_name.singularize}_translations"
|
21
9
|
|
22
10
|
include InstanceMethods
|
23
11
|
extend ClassMethods, Migration
|
24
12
|
|
13
|
+
class_inheritable_accessor :translated_attribute_names, :translation_options
|
14
|
+
class_inheritable_writer :required_attributes
|
15
|
+
|
16
|
+
self.translated_attribute_names = attr_names.map(&:to_sym)
|
17
|
+
self.translation_options = options
|
18
|
+
|
25
19
|
after_save :save_translations!
|
20
|
+
|
26
21
|
has_many :translations, :class_name => translation_class.name,
|
27
22
|
:foreign_key => class_name.foreign_key,
|
28
|
-
:dependent => :delete_all
|
29
|
-
|
30
|
-
scope :with_translations, lambda { |locale|
|
31
|
-
conditions = required_attributes.map do |attribute|
|
32
|
-
"#{quoted_translation_table_name}.#{attribute} IS NOT NULL"
|
33
|
-
end
|
34
|
-
conditions << "#{quoted_translation_table_name}.locale = ?"
|
35
|
-
{ :include => :translations, :conditions => [conditions.join(' AND '), locale] }
|
36
|
-
}
|
23
|
+
:dependent => :delete_all,
|
24
|
+
:extend => HasManyExtensions
|
37
25
|
|
38
26
|
attr_names.each { |attr_name| translated_attr_accessor(attr_name) }
|
39
27
|
end
|
40
|
-
|
28
|
+
|
41
29
|
def class_name
|
42
30
|
class_name = table_name[table_name_prefix.length..-(table_name_suffix.length + 1)].camelize
|
43
31
|
pluralize_table_names ? class_name.singularize : class_name
|
@@ -47,5 +35,11 @@ module Globalize
|
|
47
35
|
included_modules.include?(InstanceMethods)
|
48
36
|
end
|
49
37
|
end
|
38
|
+
|
39
|
+
module HasManyExtensions
|
40
|
+
def find_or_initialize_by_locale(locale)
|
41
|
+
with_locale(locale.to_s).first || build(:locale => locale.to_s)
|
42
|
+
end
|
43
|
+
end
|
50
44
|
end
|
51
45
|
end
|
@@ -24,9 +24,7 @@ module Globalize
|
|
24
24
|
|
25
25
|
def save_translations!
|
26
26
|
stash.each do |locale, attrs|
|
27
|
-
|
28
|
-
translation = record.translations.by_locale(locale.to_s).first
|
29
|
-
translation ||= record.translations.build(:locale => locale.to_s)
|
27
|
+
translation = record.translations.find_or_initialize_by_locale(locale.to_s)
|
30
28
|
attrs.each { |attr_name, value| translation[attr_name] = value }
|
31
29
|
translation.save!
|
32
30
|
end
|
@@ -35,7 +33,6 @@ module Globalize
|
|
35
33
|
|
36
34
|
def reset
|
37
35
|
cache.clear
|
38
|
-
# stash.clear
|
39
36
|
end
|
40
37
|
|
41
38
|
protected
|
@@ -43,13 +40,13 @@ module Globalize
|
|
43
40
|
def fetch_translation(locale)
|
44
41
|
locale = locale.to_sym
|
45
42
|
record.translations.loaded? ? record.translations.detect { |t| t.locale == locale } :
|
46
|
-
record.translations.
|
43
|
+
record.translations.with_locales(locale)
|
47
44
|
end
|
48
45
|
|
49
46
|
def fetch_translations(locale)
|
50
47
|
# only query if not already included with :include => translations
|
51
48
|
record.translations.loaded? ? record.translations :
|
52
|
-
record.translations.
|
49
|
+
record.translations.with_locales(Globalize.fallbacks(locale))
|
53
50
|
end
|
54
51
|
|
55
52
|
def fetch_attribute(locale, attr_name)
|
@@ -1,27 +1,54 @@
|
|
1
1
|
module Globalize
|
2
2
|
module ActiveRecord
|
3
3
|
module ClassMethods
|
4
|
-
delegate :
|
4
|
+
delegate :translated_locales, :set_translations_table_name, :to => :translation_class
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
result = yield
|
9
|
-
self.locale = previous_locale
|
10
|
-
result
|
6
|
+
def with_locales(*locales)
|
7
|
+
scoped & translation_class.with_locales(*locales)
|
11
8
|
end
|
12
9
|
|
13
|
-
def
|
14
|
-
|
10
|
+
def with_translations(*locales)
|
11
|
+
locales = translated_locales if locales.empty?
|
12
|
+
includes(:translations).with_locales(locales).with_required_attributes
|
15
13
|
end
|
16
14
|
|
17
|
-
def
|
18
|
-
|
15
|
+
def with_required_attributes
|
16
|
+
required_translated_attributes.inject(scoped) do |scope, name|
|
17
|
+
scope.where("#{translated_column_name(name)} IS NOT NULL")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_translated_attribute(name, value, locales = nil)
|
22
|
+
locales ||= Globalize.fallbacks
|
23
|
+
with_translations.where(
|
24
|
+
translated_column_name(name) => value,
|
25
|
+
translated_column_name(:locale) => locales.map(&:to_s)
|
26
|
+
)
|
19
27
|
end
|
20
28
|
|
21
29
|
def required_attributes
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
+
klass = const_get(:Translation) rescue const_set(:Translation, Class.new(Translation))
|
39
|
+
if klass.table_name == 'translations'
|
40
|
+
klass.set_table_name(translation_options[:table_name])
|
41
|
+
klass.belongs_to name.underscore.gsub('/', '_')
|
42
|
+
end
|
43
|
+
klass
|
44
|
+
end
|
45
|
+
|
46
|
+
def translations_table_name
|
47
|
+
translation_class.table_name
|
48
|
+
end
|
49
|
+
|
50
|
+
def translated_column_name(name)
|
51
|
+
"#{translation_class.table_name}.#{name}"
|
25
52
|
end
|
26
53
|
|
27
54
|
def respond_to?(method, *args, &block)
|
@@ -29,8 +56,9 @@ module Globalize
|
|
29
56
|
end
|
30
57
|
|
31
58
|
def method_missing(method, *args)
|
32
|
-
if method.to_s =~ /^
|
33
|
-
|
59
|
+
if method.to_s =~ /^find_(first_|)by_(\w+)$/ && translated_attribute_names.include?($2.to_sym)
|
60
|
+
result = with_translated_attribute($2, args.first)
|
61
|
+
$1 == 'first_' ? result.first : result
|
34
62
|
else
|
35
63
|
super
|
36
64
|
end
|
@@ -38,30 +66,15 @@ module Globalize
|
|
38
66
|
|
39
67
|
protected
|
40
68
|
|
41
|
-
def find_first_by_translated_attr_and_locales(name, value)
|
42
|
-
query = "#{translated_attr_name(name)} = ? AND #{translated_attr_name('locale')} IN (?)"
|
43
|
-
locales = Globalize.fallbacks(locale || I18n.locale).map(&:to_s)
|
44
|
-
find(
|
45
|
-
:first,
|
46
|
-
:joins => :translations,
|
47
|
-
:conditions => [query, value, locales],
|
48
|
-
:readonly => false
|
49
|
-
)
|
50
|
-
end
|
51
|
-
|
52
69
|
def translated_attr_accessor(name)
|
53
|
-
define_method "#{name}=", lambda { |value|
|
54
|
-
globalize.write(
|
70
|
+
define_method :"#{name}=", lambda { |value|
|
71
|
+
globalize.write(Globalize.locale, name, value)
|
55
72
|
self[name] = value
|
56
73
|
}
|
57
74
|
define_method name, lambda { |*args|
|
58
|
-
globalize.fetch(args.first ||
|
75
|
+
globalize.fetch(args.first || Globalize.locale, name)
|
59
76
|
}
|
60
|
-
alias_method "#{name}_before_type_cast", name
|
61
|
-
end
|
62
|
-
|
63
|
-
def translated_attr_name(name)
|
64
|
-
"#{translation_class.table_name}.#{name}"
|
77
|
+
alias_method :"#{name}_before_type_cast", name
|
65
78
|
end
|
66
79
|
end
|
67
80
|
end
|
@@ -1,21 +1,19 @@
|
|
1
1
|
module Globalize
|
2
2
|
module ActiveRecord
|
3
3
|
module InstanceMethods
|
4
|
+
delegate :translated_locales, :to => :translations
|
5
|
+
|
4
6
|
def globalize
|
5
7
|
@globalize ||= Adapter.new self
|
6
8
|
end
|
7
9
|
|
8
10
|
def attributes
|
9
|
-
|
10
|
-
attrs[name] = read_attribute(name) ||
|
11
|
-
(globalize.fetch(I18n.locale, name) rescue nil)
|
12
|
-
attrs
|
13
|
-
end
|
11
|
+
super.merge(translated_attributes)
|
14
12
|
end
|
15
13
|
|
16
14
|
def attributes=(attributes, *args)
|
17
|
-
if
|
18
|
-
|
15
|
+
if locale = attributes.try(:delete, :locale)
|
16
|
+
Globalize.with_locale(locale) { super }
|
19
17
|
else
|
20
18
|
super
|
21
19
|
end
|
@@ -24,18 +22,10 @@ module Globalize
|
|
24
22
|
def attribute_names
|
25
23
|
translated_attribute_names.map(&:to_s) + super
|
26
24
|
end
|
27
|
-
|
28
|
-
def available_locales
|
29
|
-
translations.select('DISTINCT locale').map(&:locale)
|
30
|
-
end
|
31
|
-
|
32
|
-
def translated_locales
|
33
|
-
translations.map(&:locale)
|
34
|
-
end
|
35
|
-
|
25
|
+
|
36
26
|
def translated_attributes
|
37
27
|
translated_attribute_names.inject({}) do |attributes, name|
|
38
|
-
attributes.merge(name => send(name))
|
28
|
+
attributes.merge(name.to_s => send(name))
|
39
29
|
end
|
40
30
|
end
|
41
31
|
|
@@ -12,7 +12,7 @@ module Globalize
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
self.connection.create_table(
|
15
|
+
self.connection.create_table(translations_table_name) do |t|
|
16
16
|
t.references table_name.sub(/^#{table_name_prefix}/, "").singularize
|
17
17
|
t.string :locale
|
18
18
|
fields.each do |name, type|
|
@@ -22,7 +22,7 @@ module Globalize
|
|
22
22
|
end
|
23
23
|
|
24
24
|
self.connection.add_index(
|
25
|
-
|
25
|
+
translations_table_name,
|
26
26
|
"#{table_name.sub(/^#{table_name_prefix}/, "").singularize}_id",
|
27
27
|
:name => translation_index_name
|
28
28
|
)
|
@@ -31,13 +31,13 @@ module Globalize
|
|
31
31
|
def translation_index_name
|
32
32
|
require 'digest/sha1'
|
33
33
|
# FIXME what's the max size of an index name?
|
34
|
-
index_name = "index_#{
|
34
|
+
index_name = "index_#{translations_table_name}_on_#{self.table_name.singularize}_id"
|
35
35
|
index_name.size < 50 ? index_name : "index_#{Digest::SHA1.hexdigest(index_name)}"
|
36
36
|
end
|
37
37
|
|
38
38
|
def drop_translation_table!
|
39
|
-
self.connection.remove_index(
|
40
|
-
self.connection.drop_table(
|
39
|
+
self.connection.remove_index(translations_table_name, :name => translation_index_name) rescue nil
|
40
|
+
self.connection.drop_table(translations_table_name)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Globalize
|
2
|
+
module ActiveRecord
|
3
|
+
class Translation < ::ActiveRecord::Base
|
4
|
+
class << self
|
5
|
+
def with_locales(*locales)
|
6
|
+
where(:locale => locales.flatten.map(&:to_s))
|
7
|
+
end
|
8
|
+
alias with_locale with_locales
|
9
|
+
|
10
|
+
def translated_locales
|
11
|
+
select('DISTINCT locale').map(&:locale)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def locale
|
16
|
+
read_attribute(:locale).to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
def locale=(locale)
|
20
|
+
write_attribute(:locale, locale.to_s)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/globalize/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: globalize3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sven Fuchs
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date: 2010-07-
|
21
|
+
date: 2010-07-31 00:00:00 +02:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
@@ -53,6 +53,7 @@ files:
|
|
53
53
|
- lib/globalize/active_record/class_methods.rb
|
54
54
|
- lib/globalize/active_record/instance_methods.rb
|
55
55
|
- lib/globalize/active_record/migration.rb
|
56
|
+
- lib/globalize/active_record/translation.rb
|
56
57
|
- lib/globalize/active_record.rb
|
57
58
|
- lib/globalize/version.rb
|
58
59
|
- lib/globalize.rb
|