mongoid_globalize 0.1.2 → 0.1.3

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/.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
-