Permalink
Browse files

stop ActiveRecord::Base.locale from defaulting to I18n.locale, add Ac…

…tiveRecord::Base.with_locale and make ActiveRecord::Base#attributes= accept a virtual :locale attribute.
  • Loading branch information...
1 parent 2bcc7df commit 9b6c33dc36bc0edc156f9c89dd0140d61c505f1a Sven Fuchs committed Dec 26, 2009
Showing with 58 additions and 12 deletions.
  1. +19 −4 lib/globalize/active_record.rb
  2. +17 −5 test/active_record/translates_test.rb
  3. +22 −3 test/active_record_test.rb
@@ -33,7 +33,7 @@ def locale=(locale); write_attribute(:locale, locale.to_s); end
module ActMacro
def locale
- (defined?(@@locale) && @@locale) || I18n.locale
+ (defined?(@@locale) && @@locale)
end
def locale=(locale)
@@ -86,6 +86,13 @@ def by_locales(locales)
module ClassMethods
delegate :set_translation_table_name, :to => :translation_class
+ def with_locale(locale)
+ previous_locale, self.locale = self.locale, locale
+ result = yield
+ self.locale = previous_locale
+ result
+ end
+
def translation_table_name
translation_class.table_name
end
@@ -116,17 +123,17 @@ def method_missing(method, *args)
def find_first_by_translated_attr_and_locales(name, value)
query = "#{translated_attr_name(name)} = ? AND #{translated_attr_name('locale')} IN (?)"
- locales = Globalize.fallbacks(locale).map(&:to_s)
+ locales = Globalize.fallbacks(locale || I18n.locale).map(&:to_s)
find(:first, :joins => :translations, :conditions => [query, value, locales])
end
def translated_attr_accessor(name)
define_method "#{name}=", lambda { |value|
- globalize.write(self.class.locale, name, value)
+ globalize.write(self.class.locale || I18n.locale, name, value)
self[name] = value
}
define_method name, lambda {
- globalize.fetch(self.class.locale, name)
+ globalize.fetch(self.class.locale || I18n.locale, name)
}
alias_method "#{name}_before_type_cast", name
end
@@ -141,6 +148,14 @@ def globalize
@globalize ||= Adapter.new self
end
+ def attributes=(attributes, *args)
+ if attributes.respond_to?(:delete) && locale = attributes.delete(:locale)
+ self.class.with_locale(locale) { super }
+ else
+ super
+ end
+ end
+
def available_locales
translations.scoped(:select => 'DISTINCT locale').map(&:locale)
end
@@ -9,13 +9,25 @@ def setup
end
test 'defines a :locale accessors on ActiveRecord::Base' do
- ActiveRecord::Base.locale = :'de-DE'
- assert_equal :'de-DE', ActiveRecord::Base.locale
+ ActiveRecord::Base.locale = :de
+ assert_equal :de, ActiveRecord::Base.locale
end
- test 'the :locale reader on ActiveRecord::Base defaults to I18n.locale' do
- I18n.locale = :'en-US'
- assert_equal I18n.locale, ActiveRecord::Base.locale
+ test 'the :locale reader on ActiveRecord::Base does not default to I18n.locale (anymore)' do
+ I18n.locale = :en
+ assert_nil ActiveRecord::Base.locale
+ end
+
+ test 'ActiveRecord::Base.with_locale temporarily sets the given locale and yields the block' do
+ I18n.locale = :en
+ post = Post.with_locale(:de) do
+ Post.create!(:subject => 'Titel', :content => 'Inhalt')
+ end
+ assert_nil Post.locale
+ assert_equal :en, I18n.locale
+
+ I18n.locale = :de
+ assert_equal 'Titel', post.subject
end
test 'translation_class returns the Translation class' do
View
@@ -72,6 +72,19 @@ def assert_translated(locale, record, names, expected)
assert_equal 'foo', post.subject
end
+ test "passing the locale to attributes= uses the given locale" do
+ post = Post.create(:subject => 'title', :content => 'content')
+ post.update_attributes(:subject => 'Titel', :content => 'Inhalt', :locale => :de)
+ post.reload
+
+ assert_equal :en, I18n.locale
+ assert_nil ActiveRecord::Base.locale
+
+ assert_equal 'title', post.subject
+ I18n.locale = :de
+ assert_equal 'Titel', post.subject
+ end
+
test 'reload works' do
post = Post.create(:subject => 'foo', :content => 'bar')
post.subject = 'baz'
@@ -202,13 +215,16 @@ def assert_translated(locale, record, names, expected)
test 'translated class locale setting' do
assert ActiveRecord::Base.respond_to?(:locale)
assert_equal :en, I18n.locale
- assert_equal :en, ActiveRecord::Base.locale
+ assert_nil ActiveRecord::Base.locale
+
I18n.locale = :de
assert_equal :de, I18n.locale
- assert_equal :de, ActiveRecord::Base.locale
+ assert_nil ActiveRecord::Base.locale
+
ActiveRecord::Base.locale = :es
assert_equal :de, I18n.locale
assert_equal :es, ActiveRecord::Base.locale
+
I18n.locale = :fr
assert_equal :fr, I18n.locale
assert_equal :es, ActiveRecord::Base.locale
@@ -222,6 +238,7 @@ def assert_translated(locale, record, names, expected)
ActiveRecord::Base.locale = :de
assert_equal :de, ActiveRecord::Base.locale
assert_equal :de, Parent.locale
+
Parent.locale = :es
assert_equal :es, ActiveRecord::Base.locale
assert_equal :es, Parent.locale
@@ -236,11 +253,13 @@ def assert_translated(locale, record, names, expected)
test "attribute loading goes by content locale and not global locale" do
post = Post.create(:subject => 'foo')
- assert_equal :en, ActiveRecord::Base.locale
+ assert_nil ActiveRecord::Base.locale
+
ActiveRecord::Base.locale = :de
assert_equal :en, I18n.locale
post.update_attribute(:subject, 'foo [de]')
assert_equal 'foo [de]', Post.first.subject
+
ActiveRecord::Base.locale = :en
assert_equal 'foo', Post.first.subject
end

0 comments on commit 9b6c33d

Please sign in to comment.