mongoid_globalize 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - ruby-head
6
+ - jruby
7
+ - rbx
8
+ - rbx-2.0
9
+ - ree
data/Gemfile CHANGED
@@ -1,13 +1,14 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  #gem 'mongoid', '>= 2.1', :git => 'git://github.com/mongoid/mongoid.git', :tag => '76d8692e5e0cec511c934f9f7afa15024e796f58'
4
- gem 'mongoid', '>= 2.1', :git => 'git://github.com/mongoid/mongoid.git', :tag => '2.1.2'
4
+ gem 'mongoid', '>= 2.1', :git => 'git://github.com/mongoid/mongoid.git', :tag => 'v2.3.0'
5
5
  gem 'bson_ext', '>= 1.3'
6
6
 
7
7
  group :development, :test do
8
+ gem 'rdoc'
8
9
  gem 'rspec'
9
10
  gem 'mongoid-rspec'
10
11
  gem 'database_cleaner'
11
- gem 'ruby-debug19'
12
+ gem 'ruby-debug19' if RUBY_VERSION == "1.9.2"
12
13
  gem 'jeweler'
13
14
  end
data/Gemfile.lock CHANGED
@@ -1,42 +1,47 @@
1
1
  GIT
2
2
  remote: git://github.com/mongoid/mongoid.git
3
- revision: 93b568c6d47efd76bcf817dc416385a98037a335
4
- tag: 2.1.2
3
+ revision: 3c702e6d92bb99782bf7b8a35f1e0da3bacddc93
4
+ tag: v2.3.0
5
5
  specs:
6
- mongoid (2.1.2)
7
- activemodel (~> 3.0)
8
- mongo (~> 1.3)
6
+ mongoid (2.3.0)
7
+ activemodel (~> 3.1)
8
+ mongo (~> 1.4)
9
9
  tzinfo (~> 0.3.22)
10
10
 
11
11
  GEM
12
12
  remote: http://rubygems.org/
13
13
  specs:
14
- activemodel (3.0.9)
15
- activesupport (= 3.0.9)
16
- builder (~> 2.1.2)
17
- i18n (~> 0.5.0)
18
- activesupport (3.0.9)
14
+ activemodel (3.1.0)
15
+ activesupport (= 3.1.0)
16
+ bcrypt-ruby (~> 3.0.0)
17
+ builder (~> 3.0.0)
18
+ i18n (~> 0.6)
19
+ activesupport (3.1.0)
20
+ multi_json (~> 1.0)
19
21
  archive-tar-minitar (0.5.2)
20
- bson (1.3.1)
21
- bson_ext (1.3.1)
22
- builder (2.1.2)
22
+ bcrypt-ruby (3.0.1)
23
+ bson (1.4.0)
24
+ bson_ext (1.4.0)
25
+ builder (3.0.0)
23
26
  columnize (0.3.4)
24
27
  database_cleaner (0.6.7)
25
28
  diff-lcs (1.1.2)
26
29
  git (1.2.5)
27
- i18n (0.5.0)
30
+ i18n (0.6.0)
28
31
  jeweler (1.6.4)
29
32
  bundler (~> 1.0)
30
33
  git (>= 1.2.5)
31
34
  rake
32
35
  linecache19 (0.5.12)
33
36
  ruby_core_source (>= 0.1.4)
34
- mongo (1.3.1)
35
- bson (>= 1.3.1)
37
+ mongo (1.4.0)
38
+ bson (= 1.4.0)
36
39
  mongoid-rspec (1.4.4)
37
40
  mongoid (~> 2.0)
38
41
  rspec (~> 2)
42
+ multi_json (1.0.3)
39
43
  rake (0.9.2)
44
+ rdoc (3.9.4)
40
45
  rspec (2.6.0)
41
46
  rspec-core (~> 2.6.0)
42
47
  rspec-expectations (~> 2.6.0)
@@ -55,7 +60,7 @@ GEM
55
60
  ruby-debug-base19 (>= 0.11.19)
56
61
  ruby_core_source (0.1.5)
57
62
  archive-tar-minitar (>= 0.5.2)
58
- tzinfo (0.3.29)
63
+ tzinfo (0.3.30)
59
64
 
60
65
  PLATFORMS
61
66
  ruby
@@ -66,5 +71,6 @@ DEPENDENCIES
66
71
  jeweler
67
72
  mongoid (>= 2.1)!
68
73
  mongoid-rspec
74
+ rdoc
69
75
  rspec
70
76
  ruby-debug19
data/README.textile CHANGED
@@ -1,4 +1,4 @@
1
- h1. Mongoid::Globalize
1
+ h1. "!https://secure.travis-ci.org/Mik-die/mongoid_globalize.png!":http://travis-ci.org/Mik-die/mongoid_globalize Mongoid::Globalize
2
2
 
3
3
  Mongoid::Globalize is based on Globalize3, but targeted at Mongoid. As Globalize3, it is compatible with and builds on the new "I18n API in Ruby on Rails":http://guides.rubyonrails.org/i18n.html and adds model translations to Mongoid::Document.
4
4
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
@@ -7,7 +7,25 @@ require 'mongoid_globalize/fields_builder'
7
7
  require 'mongoid_globalize/instance_methods'
8
8
 
9
9
  module Mongoid::Globalize
10
+
11
+ # When Mongoid::Globalize included into Mongoid document class, for this class
12
+ # code inside +included+ block will be executed, methods from
13
+ # Mongoid::Globalize::ClassMethods module become class methods, and methods
14
+ # from Mongoid::Globalize::InstanceMethods become instance methods, due to
15
+ # ActiveSupport::Concern mechanism.
10
16
  extend ActiveSupport::Concern
17
+
18
+ # Define some class attributes: +translated_attribute_names+ will be contain
19
+ # attributes' names, when its will be registered as translated.
20
+ # +fallbacks_for_empty_translations+ contains condition to show fallbacks for
21
+ # blank value of attribute or not.
22
+ #
23
+ # Then one side for embeded relationship with translation documents is
24
+ # created, and some callbacks for processing changed translations are defined.
25
+ #
26
+ # And then Mongoid document class extended by Mongoid::Globalize::ActMacro
27
+ # module which contains macro method +translates+ for defining translated
28
+ # fields, translations options etc.
11
29
  included do
12
30
  class_attribute :translated_attribute_names, :fallbacks_for_empty_translations
13
31
  self.translated_attribute_names = []
@@ -19,14 +37,28 @@ module Mongoid::Globalize
19
37
  end
20
38
 
21
39
  class << self
40
+ # Get current locale. If curent locale doesn't set obviously for
41
+ # Mongoid::Globalize, returns I18n locale
42
+ # Mongoid::Globalize.locale #=> :en
43
+ # Returns Symbol
22
44
  def locale
23
45
  read_locale || I18n.locale
24
46
  end
25
47
 
48
+ # Set current locale by saving it in current thread.
49
+ # Mongoid::Globalize.locale = 'ru' #=> :ru
50
+ # Param String or Symbol
51
+ # Returns Symbol or nil
26
52
  def locale=(locale)
27
53
  set_locale(locale)
28
54
  end
29
55
 
56
+ # Runs block as if given locale is setted. Don't touch current locale. Yelds
57
+ # locale into block.
58
+ # Mongoid::Globalize.with_locale(:de) { post.title = 'Titel' }
59
+ # Param String or Symbol
60
+ # Param Proc
61
+ # Returns result from block
30
62
  def with_locale(locale, &block)
31
63
  previous_locale = read_locale
32
64
  set_locale(locale)
@@ -35,25 +67,36 @@ module Mongoid::Globalize
35
67
  result
36
68
  end
37
69
 
70
+ # Runs block for each given locale.
71
+ # Mongoid::Globalize.with_locale(:ru, [:de, :fr]) { post.title = 'Title' }
72
+ # Params String or Symbol or Array of Strings or Symbols
73
+ # Param Proc
74
+ # Returns Array with results from block for each locale
38
75
  def with_locales(*locales, &block)
39
76
  locales.flatten.map do |locale|
40
77
  with_locale(locale, &block)
41
78
  end
42
79
  end
43
80
 
81
+ # Checks whether I18n respond to +fallbacks+ method.
82
+ # Returns true or false
44
83
  def fallbacks?
45
84
  I18n.respond_to?(:fallbacks)
46
85
  end
47
86
 
87
+ # Returns fallback locales for given locale if any.
88
+ # Returns Array of Symbols
48
89
  def fallbacks(locale = self.locale)
49
90
  fallbacks? ? I18n.fallbacks[locale] : [locale.to_sym]
50
91
  end
51
92
 
52
93
  protected
94
+ # Reads locale from current thread
53
95
  def read_locale
54
96
  Thread.current[:globalize_locale]
55
97
  end
56
98
 
99
+ # Writes locale to current thread
57
100
  def set_locale(locale)
58
101
  Thread.current[:globalize_locale] = locale.to_sym rescue nil
59
102
  end
@@ -1,9 +1,14 @@
1
1
  module Mongoid::Globalize
2
2
  module ActMacro
3
- # translates do
4
- # field :title
5
- # field :visible, type: Boolean
6
- # end
3
+ # Determines translation parameters: fields and options. Available inside
4
+ # block methods are defined in Mongoid::Globalize::FieldsBuilder.
5
+ # translates do
6
+ # field :title
7
+ # field :visible, type: Boolean
8
+ # fallbacks_for_empty_translations!
9
+ # end
10
+ #
11
+ # Param Proc
7
12
  def translates(&block)
8
13
  builder = FieldsBuilder.new(self)
9
14
  builder.instance_exec(&block)
@@ -1,62 +1,81 @@
1
1
  module Mongoid::Globalize
2
+ # The +Adapter+ class used for stashing translates and changes in its before
3
+ # they will be persisted or rejected.
2
4
  class Adapter
3
5
  attr_accessor :record, :stash, :translations
4
6
  private :record=, :stash=
5
7
 
8
+ # Initialises new instance of +Adapter+. Creates empty stash for storing
9
+ # translates.
10
+ # Param: translatable Class
6
11
  def initialize(record)
7
12
  self.record = record
8
13
  self.stash = Attributes.new
9
14
  end
10
15
 
16
+ # Returns value of attribute from stash for given locale.
17
+ # Param: String or Symbol - name of locale
18
+ # Param: String or Symbol - name of attribute
19
+ # Returns nil if no value finded
11
20
  def fetch_stash(locale, name)
12
21
  value = stash.read(locale, name)
13
22
  return value if value
14
23
  return nil
15
24
  end
16
25
 
26
+ # Returns value of attribute for given locale or it's fallbacks.
27
+ # Param: String or Symbol - name of locale
28
+ # Param: String or Symbol - name of attribute
29
+ # Returns nil if no value finded
17
30
  def fetch(locale, name)
18
31
  Mongoid::Globalize.fallbacks(locale).each do |fallback|
19
32
  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
33
+ return value unless fallbacks_for?(value)
24
34
  end
25
35
  return nil
26
36
  end
27
37
 
38
+ # Writes value of attribute for given locale into stash.
39
+ # Param: String or Symbol - name of locale
40
+ # Param: String or Symbol - name of attribute
41
+ # Param: Object - value of attribute
28
42
  def write(locale, name, value)
29
43
  stash.write(locale, name, value)
30
44
  end
31
45
 
46
+ # Prepares data from stash for persisting in embeded Translation documents.
47
+ # Also clears stash for further operations.
32
48
  def prepare_translations!
33
49
  stash.each do |locale, attrs|
34
- translation = record.translations.find_by_locale(locale)
35
- translation ||= record.translations.build(:locale => locale)
36
- attrs.each{ |name, value| translation[name] = value }
50
+ if attrs.any?
51
+ translation = record.translations.find_by_locale(locale)
52
+ translation ||= record.translations.build(:locale => locale)
53
+ attrs.each{ |name, value| translation[name] = value }
54
+ end
37
55
  end
38
56
  reset
39
57
  end
40
58
 
59
+ # Clears stash.
41
60
  def reset
42
61
  stash.clear
43
62
  end
44
63
 
45
64
  protected
65
+ # Returns persisted value of attribute for given locale or nil.
46
66
  def fetch_attribute(locale, name)
47
67
  translation = record.translation_for(locale)
48
68
  return translation && translation.send(name)
49
69
  end
50
70
 
51
- def set_metadata(object, metadata)
52
- object.translation_metadata.merge!(meta_data) if object.respond_to?(:translation_metadata)
53
- object
54
- end
55
-
71
+ # Checks if +object+ needs fallbacks
72
+ # Param: Object
73
+ # Result: true or false
56
74
  def fallbacks_for?(object)
57
75
  object.nil? || (fallbacks_for_empty_translations? && object.blank?)
58
76
  end
59
77
 
78
+ # Checks option +fallbacks_for_empty_translations+
60
79
  def fallbacks_for_empty_translations?
61
80
  record.fallbacks_for_empty_translations
62
81
  end
@@ -3,20 +3,36 @@
3
3
 
4
4
  module Mongoid::Globalize
5
5
  class Attributes < Hash # TODO: Think about using HashWithIndifferentAccess ?
6
+ # Returns translations for given locale. Creates empty hash for locale, if
7
+ # given locale doesn't present.
8
+ # Param: String or Symbol - locale
9
+ # Result: Hash of translations
6
10
  def [](locale)
7
11
  locale = locale.to_sym
8
12
  self[locale] = {} unless has_key?(locale)
9
13
  self.fetch(locale)
10
14
  end
11
15
 
16
+ # Checks that given locale has translation for given name.
17
+ # Param: String or Symbol - locale
18
+ # Param: String or Symbol - name of field
19
+ # Result: true or false
12
20
  def contains?(locale, name)
13
21
  self[locale].has_key?(name.to_s)
14
22
  end
15
23
 
24
+ # Returns translation for given name and given locale.
25
+ # Param: String or Symbol - locale
26
+ # Param: String or Symbol - name of field
27
+ # Result: Object
16
28
  def read(locale, name)
17
29
  self[locale][name.to_s]
18
30
  end
19
31
 
32
+ # Writes translation for given name and given locale.
33
+ # Param: String or Symbol - locale
34
+ # Param: String or Symbol - name of field
35
+ # Param: Object
20
36
  def write(locale, name, value)
21
37
  #raise 'z' if value.nil? # TODO
22
38
  self[locale][name.to_s] = value
@@ -1,14 +1,22 @@
1
1
  module Mongoid::Globalize
2
2
  module ClassMethods
3
+ # Returns all locales used for translation all of documents of this class.
4
+ # Return Array of Symbols
3
5
  def translated_locales
4
6
  all.distinct("translations.locale").sort.map &:to_sym
5
7
  end
6
8
 
9
+ # Finds documents where translations for given locales are present and where
10
+ # attributes with presence validations aren't nil
11
+ # Params String or Symbol or Array of Strings or Symbols
12
+ # Returns Mongoid::Criteria
7
13
  def with_translations(*locales)
8
14
  locales = translated_locales if locales.empty?
9
15
  where :translations.matches => {:locale => {"$in" => locales.flatten}}.merge(required_fields_criteria)
10
16
  end
11
17
 
18
+ # Returns structures hash of attributes with presence validations for using
19
+ # in +with_translations+
12
20
  def required_fields_criteria
13
21
  required_translated_attributes.inject({}) do |criteria, name|
14
22
  criteria.merge name => {"$ne" => nil}
@@ -28,18 +36,27 @@ module Mongoid::Globalize
28
36
  # "translations.#{name}".to_sym
29
37
  #end
30
38
 
39
+ # Checks whether field with given name is translated field.
40
+ # Param String or Symbol
41
+ # Returns true or false
31
42
  def translated?(name)
32
43
  translated_attribute_names.include?(name.to_sym)
33
44
  end
34
45
 
46
+ # Return Array of attribute names with presence validations
35
47
  def required_attributes
36
48
  validators.map{ |v| v.attributes if v.is_a?(ActiveModel::Validations::PresenceValidator) }.flatten.compact
37
49
  end
38
50
 
51
+ # Return Array of translated attribute names with presence validations
39
52
  def required_translated_attributes
40
53
  translated_attribute_names & required_attributes
41
54
  end
42
55
 
56
+ # Returns translation class
57
+ # First use creates this class as subclass of document's class based on
58
+ # Mongoid::Globalize::DocumentTranslation, creates other side for embeded
59
+ # relationship.
43
60
  def translation_class
44
61
  @translation_class ||= begin
45
62
  klass = self.const_get(:Translation) rescue nil
@@ -52,6 +69,7 @@ module Mongoid::Globalize
52
69
  end
53
70
  end
54
71
 
72
+ # Generates accessor methods for translated attributes
55
73
  def translated_attr_accessor(name)
56
74
  define_method(:"#{name}=") do |value|
57
75
  write_attribute(name, value)
@@ -1,29 +1,46 @@
1
1
  module Mongoid::Globalize
2
+ # Base class for storing translations. All Translation classes are inherited
3
+ # from it.
2
4
  class DocumentTranslation
3
5
  include Mongoid::Document
6
+
4
7
  field :locale
8
+
5
9
  class << self
10
+ # Accessor to document class which translated
6
11
  attr_accessor :translated_klass
7
12
 
13
+ # Scope for searching only in given locales
14
+ # Params: String or Symbol - locales
15
+ # Returns Mongoid::Criteria
8
16
  def with_locales(*locales)
9
17
  locales = locales.flatten.map(&:to_s)
10
18
  where(:locale.in => locales)
11
19
  end
12
20
  alias with_locale with_locales
13
21
 
22
+ # Returns all locales used for translation.
23
+ # Return Array of Symbols
14
24
  def translated_locales
15
- all.distinct("locale").sort.map &:to_sym
25
+ all.distinct("locale").sort{ |x,y| x.to_s <=> y.to_s }.map &:to_sym
16
26
  end
17
27
 
28
+ # Returns translation document for given locale
29
+ # Param: String or Symbol - locale
30
+ # Return: Translation
18
31
  def find_by_locale(locale)
19
32
  with_locale(locale.to_s).first
20
33
  end
21
34
  end
22
35
 
36
+ # Reader for +locale+ attribute
37
+ # Return Symbol
23
38
  def locale
24
39
  read_attribute(:locale).to_sym
25
40
  end
26
41
 
42
+ # Writer for +locale+ attribute
43
+ # Param: String or Symbol - locale
27
44
  def locale=(locale)
28
45
  write_attribute(:locale, locale.to_s)
29
46
  end
@@ -1,15 +1,21 @@
1
1
  module Mongoid::Globalize
2
2
  class FieldsBuilder
3
+ # Initializes new istance of FieldsBuilder.
4
+ # Param Class
3
5
  def initialize(model)
4
6
  @model = model
5
7
  end
6
8
 
9
+ # Creates new field in translation document.
10
+ # Param String or Symbol
11
+ # Other params are the same as for Mongoid's +field+
7
12
  def field(name, *params)
8
13
  @model.translated_attribute_names.push name.to_sym
9
14
  @model.translated_attr_accessor(name)
10
15
  @model.translation_class.field name, *params
11
16
  end
12
17
 
18
+ # Sets +fallbacks_for_empty_translations+ option.
13
19
  def fallbacks_for_empty_translations!
14
20
  @model.fallbacks_for_empty_translations = true
15
21
  end
@@ -2,10 +2,17 @@ module Mongoid::Globalize
2
2
  module InstanceMethods
3
3
  delegate :translated_locales, :to => :translations
4
4
 
5
+ # Reader for adapter, where translations stashing during lifecicle. At first
6
+ # use creates new one.
7
+ # Return: Mongoid::Globalize::Adapter
5
8
  def globalize
6
9
  @globalize ||= Adapter.new(self)
7
10
  end
8
11
 
12
+ # The most trouble method of Mongoid::Globalize :-(
13
+ # Extends reader for @attributes. Mixes translated attributes to Mongoid
14
+ # @attributes.
15
+ # Return: Hash
9
16
  def attributes
10
17
  unless @stop_merging_translated_attributes
11
18
  @attributes.merge! translated_attributes
@@ -13,10 +20,21 @@ module Mongoid::Globalize
13
20
  super
14
21
  end
15
22
 
23
+ # Extends Mongoid::Document's method +process+. Pocesses given attributes in
24
+ # consideration of possible :locale key. Used by Mongoid for all attribute-
25
+ # related operations, such as +create+, +update+ etc.
26
+ # Param: Hash of attributes
27
+ # Other params will be transmitted into Mongoid::Document's method +process+
28
+ # as is.
16
29
  def process(attributes, *args)
17
30
  with_given_locale(attributes) { super }
18
31
  end
19
32
 
33
+ # Extends Mongoid::Document's method +write_attribute+. If writed attribute
34
+ # is translateble, it is placed into adapter's stash.
35
+ # Param: String or Symbol - name of attribute
36
+ # Param: Object - value of attribute
37
+ # Param: Hash of options
20
38
  def write_attribute(name, value, options = {})
21
39
  if translated?(name)
22
40
  options = {:locale => nil}.merge(options)
@@ -25,12 +43,19 @@ module Mongoid::Globalize
25
43
  attribute_will_change! access
26
44
  end
27
45
  @translated_attributes[access] = value
28
- globalize.write(options[:locale] || Mongoid::Globalize.locale, name, value)
46
+ the_locale = options[:locale] || Mongoid::Globalize.locale
47
+ self.translations.reject!{ |t| t.new_record? && t.locale != the_locale }
48
+ globalize.write(the_locale, name, value)
29
49
  else
30
50
  super(name, value)
31
51
  end
32
52
  end
33
53
 
54
+ # Extends Mongoid::Document's method +read_attribute+. If writed attribute
55
+ # is translateble, it is readed from adapter's stash.
56
+ # Param: String or Symbol - name of attribute
57
+ # Param: Hash of options
58
+ # Return: Object - value of attribute
34
59
  def read_attribute(name, options = {})
35
60
  options = {:translated => true, :locale => nil}.merge(options)
36
61
  if translated?(name) and options[:translated]
@@ -47,21 +72,28 @@ module Mongoid::Globalize
47
72
 
48
73
  # Mongoid documents haven't attribute_names method, so I replace +super+
49
74
  # with +@attributes.keys.sort+. So this method returns only translated and
50
- # existing attribute names (but not all available names as in AR or G3)
75
+ # existing attribute names (but not all available names as in AR or G3)
51
76
  def attribute_names
52
77
  translated_attribute_names.map(&:to_s) + @attributes.keys.sort
53
78
  end
54
79
 
80
+ # Checks whether field with given name is translated field.
81
+ # Param String or Symbol
82
+ # Returns true or false
55
83
  def translated?(name)
56
84
  self.class.translated?(name)
57
85
  end
58
86
 
87
+ # Returns translations for current locale. Is used for initial mixing into
88
+ # @attributes hash. Actual translations are in @translated_attributes hash.
89
+ # Return Hash
59
90
  def translated_attributes
60
91
  @translated_attributes ||= translated_attribute_names.inject({}) do |attrs, name|
61
92
  attrs.merge(name.to_s => translation.send(name))
62
93
  end
63
94
  end
64
95
 
96
+ # TODO:
65
97
  def untranslated_attributes
66
98
  attrs = {}
67
99
  attribute_names.each do |name|
@@ -70,6 +102,13 @@ module Mongoid::Globalize
70
102
  attrs
71
103
  end
72
104
 
105
+ # Updates fields separately for each given locale
106
+ # post.set_translations(
107
+ # :en => { :title => "updated title" },
108
+ # :de => { :content => "geänderter Inhalt" }
109
+ # )
110
+ # Param: Hash, where keys are locales and values are Hashes of name-value
111
+ # pairs for fields.
73
112
  def set_translations(options)
74
113
  options.keys.each do |locale|
75
114
  translation = translation_for(locale) || translations.build(:locale => locale.to_s)
@@ -77,17 +116,19 @@ module Mongoid::Globalize
77
116
  end
78
117
  end
79
118
 
119
+ # Extends Mongoid::Document's method +reload+. Resets all translation
120
+ # changes.
80
121
  def reload
81
122
  translated_attribute_names.each { |name| @attributes.delete(name.to_s) }
82
123
  globalize.reset
83
124
  super
84
125
  end
85
126
 
127
+ # Extends Mongoid::Document's method +clone+. Adds to cloned object all
128
+ # translations from original object.
86
129
  def clone
87
130
  obj = super
88
131
  return obj unless respond_to?(:translated_attribute_names)
89
-
90
- # obj.instance_variable_set(:@translations, nil) if new_record?
91
132
  obj.instance_variable_set(:@globalize, nil )
92
133
  each_locale_and_translated_attribute do |locale, name|
93
134
  obj.globalize.write(locale, name, globalize.fetch(locale, name) )
@@ -95,10 +136,13 @@ module Mongoid::Globalize
95
136
  return obj
96
137
  end
97
138
 
139
+ # Returns instance of Translation for current locale.
98
140
  def translation
99
141
  translation_for(Mongoid::Globalize.locale)
100
142
  end
101
143
 
144
+ # Returns instance of Translation for given locale.
145
+ # Param String or Symbol
102
146
  def translation_for(locale)
103
147
  @translation_caches ||= {}
104
148
  # Need to temporary switch of merging, because #translations uses
@@ -114,6 +158,8 @@ module Mongoid::Globalize
114
158
  end
115
159
 
116
160
  protected
161
+ # Executes given block for each locale and translated attribute name for
162
+ # this document.
117
163
  def each_locale_and_translated_attribute
118
164
  used_locales.each do |locale|
119
165
  translated_attribute_names.each do |name|
@@ -122,12 +168,15 @@ module Mongoid::Globalize
122
168
  end
123
169
  end
124
170
 
171
+ # Return Array with locales, used for translation of this document
125
172
  def used_locales
126
173
  locales = globalize.stash.keys.concat(globalize.stash.keys).concat(translations.translated_locales)
127
174
  locales.uniq!
128
175
  locales
129
176
  end
130
177
 
178
+ # Before save callback. Cleans @attributes hash from translated attributes
179
+ # and prepares them for persisting.
131
180
  def prepare_translations!
132
181
  @stop_merging_translated_attributes = true
133
182
  translated_attribute_names.each do |name|
@@ -137,11 +186,15 @@ module Mongoid::Globalize
137
186
  globalize.prepare_translations!
138
187
  end
139
188
 
189
+ # After save callback. Reset some values.
140
190
  def clear_translations!
141
191
  @translation_caches = {}
142
192
  @stop_merging_translated_attributes = nil
143
193
  end
144
194
 
195
+ # Detects locale in given attributes and executes given block for it.
196
+ # Param: Hash of attributes
197
+ # Param: Proc
145
198
  def with_given_locale(attributes, &block)
146
199
  attributes.symbolize_keys! if attributes.respond_to?(:symbolize_keys!)
147
200
  if locale = attributes.try(:delete, :locale)
@@ -4,20 +4,21 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{mongoid_globalize}
8
- s.version = "0.1.2"
7
+ s.name = "mongoid_globalize"
8
+ s.version = "0.1.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Mik-die"]
12
- s.date = %q{2011-08-01}
13
- s.description = %q{Library for translating Mongoid documents, based on Globalize3 principles}
14
- s.email = %q{MikDiet@gmail.com}
12
+ s.date = "2011-10-09"
13
+ s.description = "Library for translating Mongoid documents, based on Globalize3 principles"
14
+ s.email = "MikDiet@gmail.com"
15
15
  s.extra_rdoc_files = [
16
16
  "README.textile"
17
17
  ]
18
18
  s.files = [
19
19
  ".rspec",
20
20
  ".rvmrc",
21
+ ".travis.yml",
21
22
  "Gemfile",
22
23
  "Gemfile.lock",
23
24
  "MIT-LICENSE",
@@ -45,11 +46,11 @@ Gem::Specification.new do |s|
45
46
  "spec/mongoid_globalize_spec.rb",
46
47
  "spec/spec_helper.rb"
47
48
  ]
48
- s.homepage = %q{http://github.com/Mik-die/mongoid_globalize}
49
+ s.homepage = "http://github.com/Mik-die/mongoid_globalize"
49
50
  s.licenses = ["MIT"]
50
51
  s.require_paths = ["lib"]
51
- s.rubygems_version = %q{1.6.2}
52
- s.summary = %q{Library for translating Mongoid documents}
52
+ s.rubygems_version = "1.8.10"
53
+ s.summary = "Library for translating Mongoid documents"
53
54
 
54
55
  if s.respond_to? :specification_version then
55
56
  s.specification_version = 3
@@ -57,6 +58,7 @@ Gem::Specification.new do |s|
57
58
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
58
59
  s.add_runtime_dependency(%q<mongoid>, [">= 2.1"])
59
60
  s.add_runtime_dependency(%q<bson_ext>, [">= 1.3"])
61
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
60
62
  s.add_development_dependency(%q<rspec>, [">= 0"])
61
63
  s.add_development_dependency(%q<mongoid-rspec>, [">= 0"])
62
64
  s.add_development_dependency(%q<database_cleaner>, [">= 0"])
@@ -65,6 +67,7 @@ Gem::Specification.new do |s|
65
67
  else
66
68
  s.add_dependency(%q<mongoid>, [">= 2.1"])
67
69
  s.add_dependency(%q<bson_ext>, [">= 1.3"])
70
+ s.add_dependency(%q<rdoc>, [">= 0"])
68
71
  s.add_dependency(%q<rspec>, [">= 0"])
69
72
  s.add_dependency(%q<mongoid-rspec>, [">= 0"])
70
73
  s.add_dependency(%q<database_cleaner>, [">= 0"])
@@ -74,6 +77,7 @@ Gem::Specification.new do |s|
74
77
  else
75
78
  s.add_dependency(%q<mongoid>, [">= 2.1"])
76
79
  s.add_dependency(%q<bson_ext>, [">= 1.3"])
80
+ s.add_dependency(%q<rdoc>, [">= 0"])
77
81
  s.add_dependency(%q<rspec>, [">= 0"])
78
82
  s.add_dependency(%q<mongoid-rspec>, [">= 0"])
79
83
  s.add_dependency(%q<database_cleaner>, [">= 0"])
data/spec/data/models.rb CHANGED
@@ -5,8 +5,8 @@ class Post
5
5
  translates do
6
6
  field :title
7
7
  field :content
8
- field :published, type: Boolean
9
- field :published_at, type: DateTime
8
+ field :published, :type => Boolean
9
+ field :published_at, :type => DateTime
10
10
  end
11
11
  validates_presence_of :title
12
12
  scope :with_some_title, :conditions => { :title => 'some_title' }
@@ -17,8 +17,8 @@ class PostTranslation
17
17
  field :locale
18
18
  field :title
19
19
  field :content
20
- field :published, type: Boolean
21
- field :published_at, type: DateTime
20
+ field :published, :type => Boolean
21
+ field :published_at, :type => DateTime
22
22
  embedded_in :post
23
23
 
24
24
  def existing_method
@@ -17,7 +17,7 @@ describe "Fallbacks" do
17
17
  I18n.backend = @previous_backend
18
18
  end
19
19
 
20
- it "keep one field in new locale when other field is changed" do
20
+ it "keeps one field in new locale when other field is changed" do
21
21
  I18n.fallbacks.map('de-DE' => [ 'en-US' ])
22
22
  post = Post.create :title => 'foo'
23
23
  I18n.locale = 'de-DE'
@@ -25,7 +25,7 @@ describe "Fallbacks" do
25
25
  post.title.should == 'foo'
26
26
  end
27
27
 
28
- it "modify non-required field in a new locale" do
28
+ it "modifies non-required field in a new locale" do
29
29
  I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
30
30
  post = Post.create :title => 'foo'
31
31
  I18n.locale = 'de-DE'
@@ -33,7 +33,7 @@ describe "Fallbacks" do
33
33
  post.save.should be_true
34
34
  end
35
35
 
36
- it "resolve a simple fallback" do
36
+ it "resolves a simple fallback" do
37
37
  I18n.locale = 'de-DE'
38
38
  post = Post.create :title => 'foo'
39
39
 
@@ -47,7 +47,7 @@ describe "Fallbacks" do
47
47
  post.content.should == 'bar'
48
48
  end
49
49
 
50
- it "resolve a simple fallback without reloading" do
50
+ it "resolves a simple fallback without reloading" do
51
51
  I18n.locale = 'de-DE'
52
52
  post = Post.new :title => 'foo'
53
53
 
@@ -60,7 +60,7 @@ describe "Fallbacks" do
60
60
  post.content.should == 'bar'
61
61
  end
62
62
 
63
- it "resolve a complex fallback without reloading" do
63
+ it "resolves a complex fallback without reloading" do
64
64
  I18n.fallbacks.map 'de' => %w(en he)
65
65
  I18n.locale = 'de'
66
66
  post = Post.new
@@ -74,7 +74,7 @@ describe "Fallbacks" do
74
74
  post.content.should == 'bar'
75
75
  end
76
76
 
77
- it 'work with lots of locale switching' do
77
+ it 'works with lots of locale switching' do
78
78
  I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
79
79
  post = Post.create :title => 'foo'
80
80
  I18n.locale = :'de-DE'
@@ -86,7 +86,7 @@ describe "Fallbacks" do
86
86
  post.title.should == 'bar'
87
87
  end
88
88
 
89
- it 'work with lots of locale switching 2' do
89
+ it 'works with lots of locale switching 2' do
90
90
  I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
91
91
  child = Child.create :content => 'foo'
92
92
  I18n.locale = :'de-DE'
@@ -98,7 +98,7 @@ describe "Fallbacks" do
98
98
  child.content.should == 'bar'
99
99
  end
100
100
 
101
- it 'work with nil translations' do
101
+ it 'works with nil translations' do
102
102
  I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
103
103
  post = Post.create :title => 'foo'
104
104
  I18n.locale = :'de-DE'
@@ -108,7 +108,7 @@ describe "Fallbacks" do
108
108
  post.title.should == 'foo'
109
109
  end
110
110
 
111
- it 'work with empty translations' do
111
+ it 'works with empty translations' do
112
112
  I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
113
113
  task = Task.create :name => 'foo'
114
114
  I18n.locale = :'de-DE'
@@ -118,7 +118,7 @@ describe "Fallbacks" do
118
118
  task.name.should == 'foo'
119
119
  end
120
120
 
121
- it 'work with empty translations 2' do
121
+ it 'works with empty translations 2' do
122
122
  I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
123
123
  task = Task.create :name => 'foo'
124
124
  post = Post.create :title => 'foo'
@@ -132,4 +132,15 @@ describe "Fallbacks" do
132
132
  post.update_attribute :title, ''
133
133
  post.title.should == ''
134
134
  end
135
+
136
+ it "creates just one translation when fallbacks set" do
137
+ I18n.fallbacks.clear
138
+ I18n.fallbacks.map :de => [:fr]
139
+ I18n.locale = :de
140
+ task = Task.create :name => 'foo'
141
+ task.translations.should be_any(&:persisted?)
142
+
143
+ task.save
144
+ task.translations.map(&:locale).sort.should == [:de]
145
+ end
135
146
  end
@@ -10,10 +10,8 @@ describe "#set_translations" do
10
10
  :de => { :title => 'geänderter Titel', :content => 'geänderter Inhalt' }
11
11
  )
12
12
  post.reload
13
- post.should be_translated(:en).for([:title, :content])
14
- .as(['updated title', 'updated content'])
15
- post.should be_translated(:de).for([:title, :content])
16
- .as(['geänderter Titel', 'geänderter Inhalt'])
13
+ post.should be_translated(:en).for([:title, :content]).as(['updated title', 'updated content'])
14
+ post.should be_translated(:de).for([:title, :content]).as(['geänderter Titel', 'geänderter Inhalt'])
17
15
  end
18
16
 
19
17
  it "does not touch existing translations for other locales" do
@@ -21,8 +19,7 @@ describe "#set_translations" do
21
19
  post.update_attributes(:title => 'Titel', :content => 'Inhalt', :locale => :de)
22
20
  post.set_translations(:en => { :title => 'updated title', :content => 'updated content' })
23
21
  post.reload
24
- post.should be_translated(:en).for([:title, :content])
25
- .as(['updated title', 'updated content'])
22
+ post.should be_translated(:en).for([:title, :content]).as(['updated title', 'updated content'])
26
23
  post.should be_translated(:de).for([:title, :content]).as(['Titel', 'Inhalt'])
27
24
  end
28
25
 
data/spec/spec_helper.rb CHANGED
@@ -5,7 +5,9 @@ require 'mongoid'
5
5
  Mongoid.configure do |config|
6
6
  name = "mongoid_globalize_test"
7
7
  config.autocreate_indexes = true
8
- config.master = Mongo::Connection.new.db(name)
8
+ db = Mongo::Connection.new.db(name)
9
+ db.add_user("mongoid", "test")
10
+ config.master = db
9
11
  config.logger = Logger.new($stdout, :warn)
10
12
  end
11
13
 
metadata CHANGED
@@ -1,106 +1,114 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mongoid_globalize
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
4
5
  prerelease:
5
- version: 0.1.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Mik-die
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-08-01 00:00:00 +08:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2011-10-09 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: mongoid
18
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70187719513460 !ruby/object:Gem::Requirement
19
17
  none: false
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "2.1"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '2.1'
24
22
  type: :runtime
25
23
  prerelease: false
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
24
+ version_requirements: *70187719513460
25
+ - !ruby/object:Gem::Dependency
28
26
  name: bson_ext
29
- requirement: &id002 !ruby/object:Gem::Requirement
27
+ requirement: &70187719512860 !ruby/object:Gem::Requirement
30
28
  none: false
31
- requirements:
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: "1.3"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '1.3'
35
33
  type: :runtime
36
34
  prerelease: false
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *70187719512860
36
+ - !ruby/object:Gem::Dependency
37
+ name: rdoc
38
+ requirement: &70187719512220 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70187719512220
47
+ - !ruby/object:Gem::Dependency
39
48
  name: rspec
40
- requirement: &id003 !ruby/object:Gem::Requirement
49
+ requirement: &70187719511620 !ruby/object:Gem::Requirement
41
50
  none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- version: "0"
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
46
55
  type: :development
47
56
  prerelease: false
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
57
+ version_requirements: *70187719511620
58
+ - !ruby/object:Gem::Dependency
50
59
  name: mongoid-rspec
51
- requirement: &id004 !ruby/object:Gem::Requirement
60
+ requirement: &70187719511020 !ruby/object:Gem::Requirement
52
61
  none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: "0"
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
57
66
  type: :development
58
67
  prerelease: false
59
- version_requirements: *id004
60
- - !ruby/object:Gem::Dependency
68
+ version_requirements: *70187719511020
69
+ - !ruby/object:Gem::Dependency
61
70
  name: database_cleaner
62
- requirement: &id005 !ruby/object:Gem::Requirement
71
+ requirement: &70187719510440 !ruby/object:Gem::Requirement
63
72
  none: false
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: "0"
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
68
77
  type: :development
69
78
  prerelease: false
70
- version_requirements: *id005
71
- - !ruby/object:Gem::Dependency
79
+ version_requirements: *70187719510440
80
+ - !ruby/object:Gem::Dependency
72
81
  name: ruby-debug19
73
- requirement: &id006 !ruby/object:Gem::Requirement
82
+ requirement: &70187719509840 !ruby/object:Gem::Requirement
74
83
  none: false
75
- requirements:
76
- - - ">="
77
- - !ruby/object:Gem::Version
78
- version: "0"
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
79
88
  type: :development
80
89
  prerelease: false
81
- version_requirements: *id006
82
- - !ruby/object:Gem::Dependency
90
+ version_requirements: *70187719509840
91
+ - !ruby/object:Gem::Dependency
83
92
  name: jeweler
84
- requirement: &id007 !ruby/object:Gem::Requirement
93
+ requirement: &70187719509300 !ruby/object:Gem::Requirement
85
94
  none: false
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: "0"
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
90
99
  type: :development
91
100
  prerelease: false
92
- version_requirements: *id007
101
+ version_requirements: *70187719509300
93
102
  description: Library for translating Mongoid documents, based on Globalize3 principles
94
103
  email: MikDiet@gmail.com
95
104
  executables: []
96
-
97
105
  extensions: []
98
-
99
- extra_rdoc_files:
106
+ extra_rdoc_files:
100
107
  - README.textile
101
- files:
108
+ files:
102
109
  - .rspec
103
110
  - .rvmrc
111
+ - .travis.yml
104
112
  - Gemfile
105
113
  - Gemfile.lock
106
114
  - MIT-LICENSE
@@ -127,36 +135,32 @@ files:
127
135
  - spec/mongoid_globalize/validations_spec.rb
128
136
  - spec/mongoid_globalize_spec.rb
129
137
  - spec/spec_helper.rb
130
- has_rdoc: true
131
138
  homepage: http://github.com/Mik-die/mongoid_globalize
132
- licenses:
139
+ licenses:
133
140
  - MIT
134
141
  post_install_message:
135
142
  rdoc_options: []
136
-
137
- require_paths:
143
+ require_paths:
138
144
  - lib
139
- required_ruby_version: !ruby/object:Gem::Requirement
145
+ required_ruby_version: !ruby/object:Gem::Requirement
140
146
  none: false
141
- requirements:
142
- - - ">="
143
- - !ruby/object:Gem::Version
144
- hash: 335685075
145
- segments:
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ segments:
146
152
  - 0
147
- version: "0"
148
- required_rubygems_version: !ruby/object:Gem::Requirement
153
+ hash: -2938896699039716932
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
155
  none: false
150
- requirements:
151
- - - ">="
152
- - !ruby/object:Gem::Version
153
- version: "0"
156
+ requirements:
157
+ - - ! '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
154
160
  requirements: []
155
-
156
161
  rubyforge_project:
157
- rubygems_version: 1.6.2
162
+ rubygems_version: 1.8.10
158
163
  signing_key:
159
164
  specification_version: 3
160
165
  summary: Library for translating Mongoid documents
161
166
  test_files: []
162
-