mongoid_globalize 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +74 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +0 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/lib/mongoid_globalize/act_macro.rb +23 -0
- data/lib/mongoid_globalize/adapter.rb +73 -0
- data/lib/mongoid_globalize/attributes.rb +25 -0
- data/lib/mongoid_globalize/class_methods.rb +64 -0
- data/lib/mongoid_globalize/document_translation.rb +30 -0
- data/lib/mongoid_globalize/instance_methods.rb +174 -0
- data/lib/mongoid_globalize.rb +69 -0
- data/mongoid_globalize.gemspec +86 -0
- data/spec/data/models.rb +77 -0
- data/spec/mongoid_globalize/attributes_spec.rb +138 -0
- data/spec/mongoid_globalize/clone_spec.rb +51 -0
- data/spec/mongoid_globalize/dirty_tracking_spec.rb +62 -0
- data/spec/mongoid_globalize/fallbacks_spec.rb +135 -0
- data/spec/mongoid_globalize/locale_spec.rb +89 -0
- data/spec/mongoid_globalize/set_translations_spec.rb +49 -0
- data/spec/mongoid_globalize/translation_class_spec.rb +57 -0
- data/spec/mongoid_globalize/validations_spec.rb +93 -0
- data/spec/mongoid_globalize_spec.rb +173 -0
- data/spec/spec_helper.rb +77 -0
- metadata +170 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.9.2@mongoid-globalize --create
|
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'activemodel', '3.1.0.rc4'
|
4
|
+
gem 'mongoid', :git => 'git://github.com/mongoid/mongoid.git'
|
5
|
+
gem 'bson_ext'
|
6
|
+
|
7
|
+
group :development, :test do
|
8
|
+
gem 'rspec'
|
9
|
+
gem 'mongoid-rspec'
|
10
|
+
gem 'database_cleaner'
|
11
|
+
gem 'ruby-debug19'
|
12
|
+
gem 'jeweler'
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/mongoid/mongoid.git
|
3
|
+
revision: e2540c818ebb1d37b3a8d1b7e6dd6836ce16d445
|
4
|
+
specs:
|
5
|
+
mongoid (2.1.0)
|
6
|
+
activemodel (~> 3.0)
|
7
|
+
mongo (~> 1.3)
|
8
|
+
tzinfo (~> 0.3.22)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
activemodel (3.1.0.rc4)
|
14
|
+
activesupport (= 3.1.0.rc4)
|
15
|
+
bcrypt-ruby (~> 2.1.4)
|
16
|
+
builder (~> 3.0.0)
|
17
|
+
i18n (~> 0.6)
|
18
|
+
activesupport (3.1.0.rc4)
|
19
|
+
multi_json (~> 1.0)
|
20
|
+
archive-tar-minitar (0.5.2)
|
21
|
+
bcrypt-ruby (2.1.4)
|
22
|
+
bson (1.3.1)
|
23
|
+
bson_ext (1.3.1)
|
24
|
+
builder (3.0.0)
|
25
|
+
columnize (0.3.4)
|
26
|
+
database_cleaner (0.6.7)
|
27
|
+
diff-lcs (1.1.2)
|
28
|
+
git (1.2.5)
|
29
|
+
i18n (0.6.0)
|
30
|
+
jeweler (1.6.4)
|
31
|
+
bundler (~> 1.0)
|
32
|
+
git (>= 1.2.5)
|
33
|
+
rake
|
34
|
+
linecache19 (0.5.12)
|
35
|
+
ruby_core_source (>= 0.1.4)
|
36
|
+
mongo (1.3.1)
|
37
|
+
bson (>= 1.3.1)
|
38
|
+
mongoid-rspec (1.4.4)
|
39
|
+
mongoid (~> 2.0)
|
40
|
+
rspec (~> 2)
|
41
|
+
multi_json (1.0.3)
|
42
|
+
rake (0.9.2)
|
43
|
+
rspec (2.6.0)
|
44
|
+
rspec-core (~> 2.6.0)
|
45
|
+
rspec-expectations (~> 2.6.0)
|
46
|
+
rspec-mocks (~> 2.6.0)
|
47
|
+
rspec-core (2.6.4)
|
48
|
+
rspec-expectations (2.6.0)
|
49
|
+
diff-lcs (~> 1.1.2)
|
50
|
+
rspec-mocks (2.6.0)
|
51
|
+
ruby-debug-base19 (0.11.25)
|
52
|
+
columnize (>= 0.3.1)
|
53
|
+
linecache19 (>= 0.5.11)
|
54
|
+
ruby_core_source (>= 0.1.4)
|
55
|
+
ruby-debug19 (0.11.6)
|
56
|
+
columnize (>= 0.3.1)
|
57
|
+
linecache19 (>= 0.5.11)
|
58
|
+
ruby-debug-base19 (>= 0.11.19)
|
59
|
+
ruby_core_source (0.1.5)
|
60
|
+
archive-tar-minitar (>= 0.5.2)
|
61
|
+
tzinfo (0.3.29)
|
62
|
+
|
63
|
+
PLATFORMS
|
64
|
+
ruby
|
65
|
+
|
66
|
+
DEPENDENCIES
|
67
|
+
activemodel (= 3.1.0.rc4)
|
68
|
+
bson_ext
|
69
|
+
database_cleaner
|
70
|
+
jeweler
|
71
|
+
mongoid!
|
72
|
+
mongoid-rspec
|
73
|
+
rspec
|
74
|
+
ruby-debug19
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rake'
|
10
|
+
require 'rdoc/task'
|
11
|
+
|
12
|
+
require 'rspec/core'
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
16
|
+
|
17
|
+
task :default => :spec
|
18
|
+
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
21
|
+
rdoc.title = 'TranslationPanel'
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
23
|
+
rdoc.rdoc_files.include('README.rdoc')
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'jeweler'
|
28
|
+
Jeweler::Tasks.new do |gem|
|
29
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
30
|
+
gem.name = "mongoid_globalize"
|
31
|
+
gem.homepage = "http://github.com/Mik-die/mongoid_globalize"
|
32
|
+
gem.license = "MIT"
|
33
|
+
gem.summary = %Q{Library for translating Mongoid documents}
|
34
|
+
gem.description = %Q{Library for translating Mongoid documents, based on Globalize3 principles}
|
35
|
+
gem.email = "MikDiet@gmail.com"
|
36
|
+
gem.authors = ["Mik-die"]
|
37
|
+
# dependencies defined in Gemfile
|
38
|
+
end
|
39
|
+
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
module ActMacro
|
3
|
+
# TODO: other interface of +translates+. Like this:
|
4
|
+
# translates do
|
5
|
+
# field :title
|
6
|
+
# field :visible, type: Boolean
|
7
|
+
# end
|
8
|
+
def translates(*attr_names_or_hashes)
|
9
|
+
attr_hash = attr_names_or_hashes.inject({}) do |hash,attr|
|
10
|
+
hash.merge(attr.is_a?(Hash) ? attr : {attr => String})
|
11
|
+
end
|
12
|
+
attr_hash.each do |name, type|
|
13
|
+
self.translated_attribute_names.push name.to_sym
|
14
|
+
translated_attr_accessor(name)
|
15
|
+
translation_class.field name, type: type
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def fallbacks_for_empty_translations!
|
20
|
+
self.fallbacks_for_empty_translations = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
class Adapter
|
3
|
+
attr_accessor :record, :stash, :translations
|
4
|
+
private :record=, :stash=
|
5
|
+
|
6
|
+
def initialize(record)
|
7
|
+
self.record = record
|
8
|
+
self.stash = Attributes.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch_stash(locale, name)
|
12
|
+
value = stash.read(locale, name)
|
13
|
+
return value if value
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch(locale, name)
|
18
|
+
Mongoid::Globalize.fallbacks(locale).each do |fallback|
|
19
|
+
value = fetch_stash(fallback, name) || fetch_attribute(fallback, name)
|
20
|
+
unless fallbacks_for?(value)
|
21
|
+
set_metadata(value, :locale => fallback, :requested_locale => locale)
|
22
|
+
return value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
return nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def write(locale, name, value)
|
29
|
+
stash.write(locale, name, value)
|
30
|
+
end
|
31
|
+
|
32
|
+
def save_translations!
|
33
|
+
stash.each do |locale, attrs|
|
34
|
+
translation = record.translations.find_or_initialize_by_locale(locale.to_s)
|
35
|
+
attrs.each{ |name, value| translation[name] = value }
|
36
|
+
translation.save!
|
37
|
+
end
|
38
|
+
# TODO: it's actual for mongoid?
|
39
|
+
#record.translations.reset
|
40
|
+
reset
|
41
|
+
end
|
42
|
+
|
43
|
+
def prepare_translations!
|
44
|
+
stash.each do |locale, attrs|
|
45
|
+
translation = record.translations.find_or_initialize_by_locale(locale.to_s)
|
46
|
+
attrs.each{ |name, value| translation[name] = value }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def reset
|
51
|
+
stash.clear
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
def fetch_attribute(locale, name)
|
56
|
+
translation = record.translation_for(locale)
|
57
|
+
return translation && translation.send(name)
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_metadata(object, metadata)
|
61
|
+
object.translation_metadata.merge!(meta_data) if object.respond_to?(:translation_metadata)
|
62
|
+
object
|
63
|
+
end
|
64
|
+
|
65
|
+
def fallbacks_for?(object)
|
66
|
+
object.nil? || (fallbacks_for_empty_translations? && object.blank?)
|
67
|
+
end
|
68
|
+
|
69
|
+
def fallbacks_for_empty_translations?
|
70
|
+
record.fallbacks_for_empty_translations
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Helper class for storing values per locale. Used by Mongoid::Globalize::Adapter
|
2
|
+
# to stash and cache attribute values.
|
3
|
+
|
4
|
+
module Mongoid::Globalize
|
5
|
+
class Attributes < Hash # TODO: Think about using HashWithIndifferentAccess ?
|
6
|
+
def [](locale)
|
7
|
+
locale = locale.to_sym
|
8
|
+
self[locale] = {} unless has_key?(locale)
|
9
|
+
self.fetch(locale)
|
10
|
+
end
|
11
|
+
|
12
|
+
def contains?(locale, name)
|
13
|
+
self[locale].has_key?(name.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def read(locale, name)
|
17
|
+
self[locale][name.to_s]
|
18
|
+
end
|
19
|
+
|
20
|
+
def write(locale, name, value)
|
21
|
+
#raise 'z' if value.nil? # TODO
|
22
|
+
self[locale][name.to_s] = value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
module ClassMethods
|
3
|
+
delegate :translated_locales, :to => :translation_class
|
4
|
+
|
5
|
+
# TODO: At first deal with +translated_locales+
|
6
|
+
#
|
7
|
+
#def with_locales(*locales)
|
8
|
+
# scoped.merge(translation_class.with_locales(*locales))
|
9
|
+
#end
|
10
|
+
#
|
11
|
+
#def with_translations(*locales)
|
12
|
+
# locales = translated_locales if locales.empty?
|
13
|
+
# includes(:translations).with_locales(locales).with_required_attributes
|
14
|
+
#end
|
15
|
+
#
|
16
|
+
#def with_required_attributes
|
17
|
+
# required_translated_attributes.inject(scoped) do |scope, name|
|
18
|
+
# scope.where("#{translated_column_name(name)} IS NOT NULL")
|
19
|
+
# end
|
20
|
+
#end
|
21
|
+
#
|
22
|
+
#def with_translated_attribute(name, value, locales = nil)
|
23
|
+
# locales ||= Globalize.fallbacks
|
24
|
+
# with_translations.where(
|
25
|
+
# translated_column_name(name) => value,
|
26
|
+
# translated_column_name(:locale) => Array(locales).map(&:to_s)
|
27
|
+
# )
|
28
|
+
#end
|
29
|
+
|
30
|
+
def translated?(name)
|
31
|
+
translated_attribute_names.include?(name.to_sym)
|
32
|
+
end
|
33
|
+
|
34
|
+
def required_attributes
|
35
|
+
validators.map{ |v| v.attributes if v.is_a?(ActiveModel::Validations::PresenceValidator) }.flatten.compact
|
36
|
+
end
|
37
|
+
|
38
|
+
def required_translated_attributes
|
39
|
+
translated_attribute_names & required_attributes
|
40
|
+
end
|
41
|
+
|
42
|
+
def translation_class
|
43
|
+
@translation_class ||= begin
|
44
|
+
klass = self.const_get(:Translation) rescue nil
|
45
|
+
if klass.nil?
|
46
|
+
klass = self.const_set(:Translation, Class.new(Mongoid::Globalize::DocumentTranslation))
|
47
|
+
end
|
48
|
+
klass.embedded_in name.underscore.gsub('/', '_')
|
49
|
+
klass
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
def translated_attr_accessor(name)
|
55
|
+
define_method(:"#{name}=") do |value|
|
56
|
+
write_attribute(name, value)
|
57
|
+
end
|
58
|
+
define_method(name) do |*args|
|
59
|
+
read_attribute(name, {:locale => args.first})
|
60
|
+
end
|
61
|
+
alias_method :"#{name}_before_type_cast", name
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
class DocumentTranslation
|
3
|
+
include Mongoid::Document
|
4
|
+
field :locale
|
5
|
+
class << self
|
6
|
+
def with_locales(*locales)
|
7
|
+
locales = locales.flatten.map(&:to_s)
|
8
|
+
where(:locale.in => locales)
|
9
|
+
end
|
10
|
+
alias with_locale with_locales
|
11
|
+
|
12
|
+
def translated_locales
|
13
|
+
# TODO
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_or_initialize_by_locale(locale)
|
18
|
+
with_locale(locale.to_s).first || build(:locale => locale.to_s)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def locale
|
23
|
+
read_attribute(:locale).to_sym
|
24
|
+
end
|
25
|
+
|
26
|
+
def locale=(locale)
|
27
|
+
write_attribute(:locale, locale.to_s)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
module InstanceMethods
|
3
|
+
delegate :translated_locales, :to => :translations
|
4
|
+
|
5
|
+
def globalize
|
6
|
+
@globalize ||= Adapter.new(self)
|
7
|
+
end
|
8
|
+
|
9
|
+
def attributes
|
10
|
+
if @stop_merging_translated_attributes
|
11
|
+
super
|
12
|
+
else
|
13
|
+
@attributes = super.merge translated_attributes
|
14
|
+
@attributes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def process(attributes, *args)
|
19
|
+
with_given_locale(attributes) { super }
|
20
|
+
end
|
21
|
+
|
22
|
+
# All of this replaced by #process.. may be :)
|
23
|
+
#def write_attributes(attributes, *args)
|
24
|
+
# with_given_locale(attributes) { super }
|
25
|
+
#end
|
26
|
+
|
27
|
+
#def update_attributes!(attributes, *args)
|
28
|
+
# with_given_locale(attributes) { super }
|
29
|
+
#end
|
30
|
+
#
|
31
|
+
#def update_attributes(attributes, *args)
|
32
|
+
# with_given_locale(attributes) { super }
|
33
|
+
#end
|
34
|
+
|
35
|
+
def write_attribute(name, value, options = {})
|
36
|
+
if translated?(name)
|
37
|
+
options = {:locale => nil}.merge(options)
|
38
|
+
access = name.to_s
|
39
|
+
unless attributes[access] == value || attribute_changed?(access)
|
40
|
+
attribute_will_change! access
|
41
|
+
end
|
42
|
+
globalize.write(options[:locale] || Mongoid::Globalize.locale, name, value)
|
43
|
+
else
|
44
|
+
super(name, value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def read_attribute(name, options = {})
|
49
|
+
options = {:translated => true, :locale => nil}.merge(options)
|
50
|
+
if translated?(name) and options[:translated]
|
51
|
+
globalize.fetch(options[:locale] || Mongoid::Globalize.locale, name)
|
52
|
+
else
|
53
|
+
super(name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# TODO
|
58
|
+
def remove_attribute(name)
|
59
|
+
super name
|
60
|
+
end
|
61
|
+
|
62
|
+
# Mongoid documents haven't attribute_names method, so I replace +super+
|
63
|
+
# with +@attributes.keys.sort+. So this method returns only translated and
|
64
|
+
# existing attribute names (but not all available names as in AR or G3)
|
65
|
+
def attribute_names
|
66
|
+
translated_attribute_names.map(&:to_s) + @attributes.keys.sort
|
67
|
+
end
|
68
|
+
|
69
|
+
def translated?(name)
|
70
|
+
self.class.translated?(name)
|
71
|
+
end
|
72
|
+
|
73
|
+
def translated_attributes
|
74
|
+
translated_attribute_names.inject({}) do |attributes, name|
|
75
|
+
attributes.merge(name.to_s => translation.send(name))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def untranslated_attributes
|
80
|
+
attrs = {}
|
81
|
+
attribute_names.each do |name|
|
82
|
+
attrs[name] = read_attribute(name, {:translated => false})
|
83
|
+
end
|
84
|
+
attrs
|
85
|
+
end
|
86
|
+
|
87
|
+
def set_translations(options)
|
88
|
+
options.keys.each do |locale|
|
89
|
+
translation = translation_for(locale) || translations.build(:locale => locale.to_s)
|
90
|
+
translation.update_attributes!(options[locale])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def reload
|
95
|
+
translated_attribute_names.each { |name| @attributes.delete(name.to_s) }
|
96
|
+
globalize.reset
|
97
|
+
super
|
98
|
+
end
|
99
|
+
|
100
|
+
def clone
|
101
|
+
obj = super
|
102
|
+
return obj unless respond_to?(:translated_attribute_names)
|
103
|
+
|
104
|
+
# obj.instance_variable_set(:@translations, nil) if new_record?
|
105
|
+
obj.instance_variable_set(:@globalize, nil )
|
106
|
+
each_locale_and_translated_attribute do |locale, name|
|
107
|
+
obj.globalize.write(locale, name, globalize.fetch(locale, name) )
|
108
|
+
end
|
109
|
+
return obj
|
110
|
+
end
|
111
|
+
|
112
|
+
def translation
|
113
|
+
translation_for(Mongoid::Globalize.locale)
|
114
|
+
end
|
115
|
+
|
116
|
+
def translation_for(locale)
|
117
|
+
@translation_caches ||= {}
|
118
|
+
unless @translation_caches[locale]
|
119
|
+
_translation = translations.detect{|t| t.locale.to_s == locale.to_s}
|
120
|
+
_translation ||= translations.build(:locale => locale)
|
121
|
+
@translation_caches[locale] = _translation
|
122
|
+
end
|
123
|
+
@translation_caches[locale]
|
124
|
+
end
|
125
|
+
|
126
|
+
protected
|
127
|
+
def each_locale_and_translated_attribute
|
128
|
+
used_locales.each do |locale|
|
129
|
+
translated_attribute_names.each do |name|
|
130
|
+
yield locale, name
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def used_locales
|
136
|
+
locales = globalize.stash.keys.concat(globalize.stash.keys).concat(translations.translated_locales)
|
137
|
+
locales.uniq!
|
138
|
+
locales
|
139
|
+
end
|
140
|
+
|
141
|
+
def unmerge_translations!
|
142
|
+
@stop_merging_translated_attributes = true
|
143
|
+
translated_attribute_names.each do |name|
|
144
|
+
@attributes.delete name.to_s
|
145
|
+
@changed_attributes.delete name.to_s
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def create_translations!
|
150
|
+
globalize.save_translations!
|
151
|
+
clear_translations!
|
152
|
+
end
|
153
|
+
|
154
|
+
def update_translations!
|
155
|
+
unmerge_translations!
|
156
|
+
globalize.prepare_translations!
|
157
|
+
globalize.reset
|
158
|
+
end
|
159
|
+
|
160
|
+
def clear_translations!
|
161
|
+
@translation_caches = {}
|
162
|
+
@stop_merging_translated_attributes = nil
|
163
|
+
end
|
164
|
+
|
165
|
+
def with_given_locale(attributes, &block)
|
166
|
+
attributes.symbolize_keys! if attributes.respond_to?(:symbolize_keys!)
|
167
|
+
if locale = attributes.try(:delete, :locale)
|
168
|
+
Mongoid::Globalize.with_locale(locale, &block)
|
169
|
+
else
|
170
|
+
yield
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'mongoid_globalize/adapter'
|
2
|
+
require 'mongoid_globalize/act_macro'
|
3
|
+
require 'mongoid_globalize/attributes'
|
4
|
+
require 'mongoid_globalize/class_methods'
|
5
|
+
require 'mongoid_globalize/document_translation'
|
6
|
+
require 'mongoid_globalize/instance_methods'
|
7
|
+
|
8
|
+
module Mongoid::Globalize
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
included do
|
11
|
+
class_attribute :translated_attribute_names, :fallbacks_for_empty_translations
|
12
|
+
self.translated_attribute_names = []
|
13
|
+
embeds_many :translations, :class_name => translation_class.name
|
14
|
+
#:extend => HasManyExtensions
|
15
|
+
before_create :unmerge_translations!
|
16
|
+
after_create :create_translations!
|
17
|
+
before_update :update_translations!
|
18
|
+
after_create :clear_translations!
|
19
|
+
|
20
|
+
extend Mongoid::Globalize::ActMacro
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def locale
|
25
|
+
read_locale || I18n.locale
|
26
|
+
end
|
27
|
+
|
28
|
+
def locale=(locale)
|
29
|
+
set_locale(locale)
|
30
|
+
end
|
31
|
+
|
32
|
+
def with_locale(locale, &block)
|
33
|
+
previous_locale = read_locale
|
34
|
+
set_locale(locale)
|
35
|
+
result = yield(locale)
|
36
|
+
set_locale(previous_locale)
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
def with_locales(*locales, &block)
|
41
|
+
locales.flatten.map do |locale|
|
42
|
+
with_locale(locale, &block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def fallbacks?
|
47
|
+
I18n.respond_to?(:fallbacks)
|
48
|
+
end
|
49
|
+
|
50
|
+
def fallbacks(locale = self.locale)
|
51
|
+
fallbacks? ? I18n.fallbacks[locale] : [locale.to_sym]
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
def read_locale
|
56
|
+
Thread.current[:globalize_locale]
|
57
|
+
end
|
58
|
+
|
59
|
+
def set_locale(locale)
|
60
|
+
Thread.current[:globalize_locale] = locale.to_sym rescue nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
#
|
64
|
+
#module HasManyExtensions
|
65
|
+
# def find_or_initialize_by_locale(locale)
|
66
|
+
# with_locale(locale.to_s).first || build(:locale => locale.to_s)
|
67
|
+
# end
|
68
|
+
#end
|
69
|
+
end
|