lolita-translation 0.3.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +25 -0
- data/Gemfile +2 -18
- data/README.md +1 -2
- data/Rakefile +1 -49
- data/app/assets/javascripts/lolita/translation/application.js +4 -3
- data/app/assets/stylesheets/lolita/translation/application.css +7 -1
- data/app/views/components/lolita/translation/_assets.html.haml +4 -0
- data/app/views/components/lolita/translation/_language_wrap.html.haml +2 -0
- data/app/views/components/lolita/translation/_switch.html.haml +4 -0
- data/lib/lolita-translation.rb +40 -33
- data/lib/lolita-translation/builder/abstract_builder.rb +103 -0
- data/lib/lolita-translation/builder/active_record_builder.rb +106 -0
- data/lib/lolita-translation/builder/mongoid_builder.rb +0 -0
- data/lib/lolita-translation/configuration.rb +41 -166
- data/lib/lolita-translation/errors.rb +15 -0
- data/lib/lolita-translation/locale.rb +32 -0
- data/lib/lolita-translation/locales.rb +62 -0
- data/lib/lolita-translation/lolita/component_hooks.rb +49 -0
- data/lib/lolita-translation/lolita/tab_extension.rb +113 -0
- data/lib/lolita-translation/migrator.rb +56 -0
- data/lib/lolita-translation/migrators/active_record_migrator.rb +93 -0
- data/lib/lolita-translation/migrators/mongoid_migrator.rb +81 -0
- data/lib/lolita-translation/orm/mixin.rb +57 -0
- data/lib/lolita-translation/rails.rb +6 -31
- data/lib/lolita-translation/record.rb +220 -0
- data/lib/lolita-translation/translated_string.rb +11 -0
- data/lib/lolita-translation/translation_class_builder.rb +59 -0
- data/lib/lolita-translation/utils.rb +13 -0
- data/lib/lolita-translation/version.rb +32 -0
- data/lib/tasks/lolita_translation.rake +14 -0
- data/lolita-translation.gemspec +24 -71
- data/spec/ar_schema.rb +90 -0
- data/spec/header.rb +14 -0
- data/spec/integrations/active_record_integration_spec.rb +218 -0
- data/spec/lolita-translation/builder/abstract_builder_spec.rb +67 -0
- data/spec/lolita-translation/builder/active_record_builder_spec.rb +40 -0
- data/spec/lolita-translation/configuration_spec.rb +72 -0
- data/spec/lolita-translation/locale_spec.rb +25 -0
- data/spec/lolita-translation/locales_spec.rb +31 -0
- data/spec/lolita-translation/lolita/tab_extension_spec.rb +61 -0
- data/spec/lolita-translation/migrator_spec.rb +42 -0
- data/spec/lolita-translation/migrators/active_record_migrator_spec.rb +50 -0
- data/spec/lolita-translation/orm/mixin_spec.rb +52 -0
- data/spec/lolita-translation/record_spec.rb +112 -0
- data/spec/lolita-translation/translation_class_builder_spec.rb +62 -0
- data/spec/lolita_translation_spec.rb +16 -0
- data/spec/rails_helper.rb +6 -0
- data/spec/requests/record_language_switch_spec.rb +16 -0
- data/spec/requests/record_saving_spec.rb +63 -0
- data/spec/spec_helper.rb +38 -90
- data/spec/tasks/lolita_translation_spec.rb +32 -0
- data/spec/test_app/app/controllers/application_controller.rb +3 -0
- data/spec/test_app/app/models/category.rb +6 -0
- data/spec/test_app/app/models/post.rb +8 -0
- data/spec/test_app/config/application.rb +24 -0
- data/spec/test_app/config/boot.rb +11 -0
- data/spec/test_app/config/database.yml +3 -0
- data/spec/test_app/config/enviroment.rb +5 -0
- data/spec/test_app/config/enviroments/development.rb +44 -0
- data/spec/test_app/config/initializers/lolita_translation.rb +4 -0
- data/spec/test_app/config/initializers/token.rb +7 -0
- data/spec/test_app/config/routes.rb +4 -0
- data/spec/test_app/db/.gitkeep +0 -0
- data/spec/test_app/log/.gitkeep +0 -0
- metadata +193 -46
- data/.document +0 -5
- data/VERSION +0 -1
- data/app/views/components/lolita/translation/_assets.html.erb +0 -7
- data/app/views/components/lolita/translation/_language_wrap.html.erb +0 -4
- data/app/views/components/lolita/translation/_switch.html.erb +0 -8
- data/lib/generators/lolita_translation/USAGE +0 -8
- data/lib/generators/lolita_translation/has_translations_generator.rb +0 -8
- data/lib/lolita-translation/model.rb +0 -100
- data/lib/lolita-translation/modules.rb +0 -130
- data/lib/lolita-translation/string.rb +0 -19
- data/lib/tasks/has_translations_tasks.rake +0 -4
- data/spec/has_translations_spec.rb +0 -43
@@ -0,0 +1,11 @@
|
|
1
|
+
class TranslatedString < String
|
2
|
+
def initialize(str, translation_record, attribute_name)
|
3
|
+
@translation_record = translation_record
|
4
|
+
@attribute_name = attribute_name
|
5
|
+
super(str)
|
6
|
+
end
|
7
|
+
|
8
|
+
def in(locale)
|
9
|
+
@translation_record.translated_attribute(@attribute_name, :locale => locale)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'lolita-translation/builder/active_record_builder'
|
2
|
+
require 'lolita-translation/builder/mongoid_builder'
|
3
|
+
require 'lolita-translation/utils'
|
4
|
+
|
5
|
+
module Lolita
|
6
|
+
module Translation
|
7
|
+
|
8
|
+
# Create ORM class for translations. For Post class it will create PostTranslation class,
|
9
|
+
# for News it will create NewsTranslation and so on
|
10
|
+
class TranslationClassBuilder
|
11
|
+
|
12
|
+
attr_reader :klass
|
13
|
+
|
14
|
+
def initialize(base_class, configuration = nil)
|
15
|
+
@klass = base_class
|
16
|
+
@configuration = configuration
|
17
|
+
detect_builder_class
|
18
|
+
end
|
19
|
+
|
20
|
+
def builder_available?
|
21
|
+
!!@builder_class
|
22
|
+
end
|
23
|
+
|
24
|
+
def builder
|
25
|
+
@builder ||= @builder_class && @builder_class.new(klass, @configuration)
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_class
|
29
|
+
if builder
|
30
|
+
builder.build
|
31
|
+
builder.klass
|
32
|
+
else
|
33
|
+
raise Lolita::Translation::NoBuilderForClassError.new(klass)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def override_attributes(attributes)
|
38
|
+
if builder
|
39
|
+
builder.override_klass_attributes(attributes)
|
40
|
+
else
|
41
|
+
raise Lolita::Translation::NoBuilderForClassError.new(klass)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def detect_builder_class
|
48
|
+
@builder_class ||= if Lolita::Translation::Utils.active_record_class?(klass)
|
49
|
+
Lolita::Translation::Builder::ActiveRecordBuilder
|
50
|
+
elsif Lolita::Translation::Utils.mongoid_class?(klass)
|
51
|
+
Lolita::Translation::Builder::MongoidBuilder
|
52
|
+
else
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Lolita
|
2
|
+
module Translation
|
3
|
+
module Utils
|
4
|
+
def self.mongoid_class?(klass)
|
5
|
+
defined?(Mongoid::Document) && klass.ancestors.include?(Mongoid::Document)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.active_record_class?(klass)
|
9
|
+
defined?(ActiveRecord::Base) && klass.ancestors.include?(ActiveRecord::Base)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Lolita
|
2
|
+
module Translation
|
3
|
+
module Version
|
4
|
+
MAJOR = 0
|
5
|
+
MINOR = 5
|
6
|
+
PATCH = 0
|
7
|
+
BUILD = nil
|
8
|
+
|
9
|
+
STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
|
10
|
+
|
11
|
+
def self.to_s
|
12
|
+
STRING
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.major
|
16
|
+
MAJOR
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.minor
|
20
|
+
MINOR
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.patch
|
24
|
+
PATCH
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.build
|
28
|
+
BUILD
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'lolita-translation'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
namespace :lolita_translation do
|
5
|
+
desc "Synca all tables at once"
|
6
|
+
task :sync_tables do
|
7
|
+
Lolita.mappings.each do |k,mapping|
|
8
|
+
klass = mapping.to
|
9
|
+
if klass && klass.respond_to?(:sync_translation_table!)
|
10
|
+
klass.sync_translation_table!
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lolita-translation.gemspec
CHANGED
@@ -1,83 +1,36 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "lolita-translation/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
6
|
+
s.name = "lolita-translation"
|
7
|
+
s.version = Lolita::Translation::Version.to_s
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["ITHouse (Latvia) and Arturs Meisters"]
|
10
|
+
s.email = "support@ithouse.lv"
|
11
|
+
s.homepage = "http://github.com/ithouse/lolita-translation"
|
12
|
+
s.summary = %q{Lolita extension that add multilanguate support to Lolita.}
|
13
|
+
s.description = %q{Lolita extension that allow users to change language and translate DB data.}
|
9
14
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["ITHouse", "Gatis Tomsons", "Arturs Meisters"]
|
12
|
-
s.date = "2011-12-20"
|
13
|
-
s.description = "Translates models in Lolita"
|
14
|
-
s.email = "support@ithouse.lv"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
17
|
"README.md"
|
18
18
|
]
|
19
|
-
s.files = [
|
20
|
-
".document",
|
21
|
-
".rspec",
|
22
|
-
"Gemfile",
|
23
|
-
"LICENSE.txt",
|
24
|
-
"README.md",
|
25
|
-
"Rakefile",
|
26
|
-
"VERSION",
|
27
|
-
"app/assets/.gitkeep",
|
28
|
-
"app/assets/javascripts/.gitkeep",
|
29
|
-
"app/assets/javascripts/lolita/translation/application.js",
|
30
|
-
"app/assets/stylesheets/lolita/translation/application.css",
|
31
|
-
"app/views/components/lolita/translation/_assets.html.erb",
|
32
|
-
"app/views/components/lolita/translation/_language_wrap.html.erb",
|
33
|
-
"app/views/components/lolita/translation/_switch.html.erb",
|
34
|
-
"config/locales/en.yml",
|
35
|
-
"config/locales/lv.yml",
|
36
|
-
"lib/generators/lolita_translation/USAGE",
|
37
|
-
"lib/generators/lolita_translation/has_translations_generator.rb",
|
38
|
-
"lib/lolita-translation.rb",
|
39
|
-
"lib/lolita-translation/configuration.rb",
|
40
|
-
"lib/lolita-translation/model.rb",
|
41
|
-
"lib/lolita-translation/modules.rb",
|
42
|
-
"lib/lolita-translation/rails.rb",
|
43
|
-
"lib/lolita-translation/string.rb",
|
44
|
-
"lib/tasks/has_translations_tasks.rake",
|
45
|
-
"lolita-translation.gemspec",
|
46
|
-
"spec/has_translations_spec.rb",
|
47
|
-
"spec/spec_helper.rb"
|
48
|
-
]
|
49
|
-
s.homepage = "http://github.com/ithouse/lolita-translations"
|
50
19
|
s.licenses = ["MIT"]
|
51
|
-
s.require_paths = ["lib"]
|
52
|
-
s.rubygems_version = "1.8.10"
|
53
|
-
s.summary = "Lolita models translation plugin"
|
54
|
-
s.test_files = [
|
55
|
-
"spec/has_translations_spec.rb",
|
56
|
-
"spec/spec_helper.rb"
|
57
|
-
]
|
58
20
|
|
59
|
-
|
60
|
-
s.specification_version = 3
|
21
|
+
s.add_runtime_dependency(%q<lolita>, ["~> 3.2.0.rc.9"])
|
61
22
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
72
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
73
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
74
|
-
end
|
75
|
-
else
|
76
|
-
s.add_dependency(%q<lolita>, [">= 3.2.0.rc.3"])
|
77
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
78
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
79
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
80
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
81
|
-
end
|
82
|
-
end
|
23
|
+
s.add_development_dependency(%q<rails>, ["~> 3.2.3"])
|
24
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.9.0"])
|
25
|
+
s.add_development_dependency(%q<rspec-rails>, ["~> 2.9.0"])
|
26
|
+
s.add_development_dependency(%q<ffaker>, ["~> 1"])
|
27
|
+
s.add_development_dependency(%q<capybara>, ["~> 1.1.2"])
|
28
|
+
s.add_development_dependency(%q<capybara-webkit>, ["~> 0.11.0"])
|
29
|
+
s.add_development_dependency(%q<cover_me>, ["~> 1.2.0"])
|
30
|
+
s.add_development_dependency(%q<sqlite3>, ["~> 1.3.6"])
|
31
|
+
s.add_development_dependency(%q<debugger>,[">0"])
|
83
32
|
|
33
|
+
s.files = `git ls-files`.split("\n")
|
34
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
end
|
data/spec/ar_schema.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
# Override connection method, to load schema on demand when there is no tables in, this allow to solve problems
|
4
|
+
# when there are different connection between rspec and capybara::session. This does not work well when data is stored
|
5
|
+
# in memory, because connection is lost in some way.
|
6
|
+
class ActiveRecord::Base
|
7
|
+
def self.connection
|
8
|
+
temp_c = retrieve_connection
|
9
|
+
if temp_c.tables.empty? && !::ARSchema.loading
|
10
|
+
::ARSchema.load_schema
|
11
|
+
end
|
12
|
+
temp_c
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Is used to load schema and clean data from table when there is any.
|
17
|
+
# Schema load is called from overrided ActiveRecord::Base.connection method.
|
18
|
+
class ARSchema
|
19
|
+
cattr_accessor :loading, :connection
|
20
|
+
@@loading = false
|
21
|
+
@connection = false
|
22
|
+
|
23
|
+
def self.connect!
|
24
|
+
unless ActiveRecord::Base.connected?
|
25
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.clean!
|
30
|
+
[:products,:products_translations,:categories,:categories_translations, :posts, :posts_translations].each do |table_name|
|
31
|
+
begin
|
32
|
+
if ActiveRecord::Base.connection.execute("SELECT count(*) FROM #{table_name}")[0]["count(*)"] > 0
|
33
|
+
ActiveRecord::Base.connection.execute("DELETE FROM #{table_name}")
|
34
|
+
end
|
35
|
+
rescue Exception => e
|
36
|
+
puts "Error: #{e}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.load_schema
|
42
|
+
# Add models
|
43
|
+
ActiveRecord::Schema.define do
|
44
|
+
::ARSchema.loading = true
|
45
|
+
create_table :products, :force => true do |t|
|
46
|
+
t.string :name
|
47
|
+
t.text :description
|
48
|
+
t.integer :price
|
49
|
+
t.integer :category_id
|
50
|
+
end
|
51
|
+
|
52
|
+
create_table :products_translations, :force => true do |t|
|
53
|
+
t.string :name
|
54
|
+
t.text :description
|
55
|
+
t.integer :product_id
|
56
|
+
t.string :locale
|
57
|
+
end
|
58
|
+
|
59
|
+
create_table :categories, :force => true do |t|
|
60
|
+
t.string :name
|
61
|
+
t.string :default_locale
|
62
|
+
end
|
63
|
+
|
64
|
+
create_table :categories_translations, :force => true do |t|
|
65
|
+
t.string :name
|
66
|
+
t.integer :category_id
|
67
|
+
t.string :locale
|
68
|
+
end
|
69
|
+
|
70
|
+
create_table :posts, :force => true do |t|
|
71
|
+
t.string :title
|
72
|
+
t.string :body
|
73
|
+
t.integer :views
|
74
|
+
end
|
75
|
+
|
76
|
+
create_table :posts_translations, :force => true do |t|
|
77
|
+
t.string :title
|
78
|
+
t.string :body
|
79
|
+
t.integer :post_id
|
80
|
+
t.string :locale
|
81
|
+
end
|
82
|
+
|
83
|
+
create_table :comments, :force => true do |t|
|
84
|
+
t.text :body
|
85
|
+
t.string :commenter
|
86
|
+
end
|
87
|
+
::ARSchema.loading = false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/spec/header.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'cover_me'
|
4
|
+
|
5
|
+
CoverMe.config do |c|
|
6
|
+
# where is your project's root:
|
7
|
+
c.project.root = File.expand_path("../lolita-translation") # => "Rails.root" (default)
|
8
|
+
|
9
|
+
# what files are you interested in coverage for:
|
10
|
+
c.file_pattern = [
|
11
|
+
/(#{CoverMe.config.project.root}\/app\/.+\.rb)/i,
|
12
|
+
/(#{CoverMe.config.project.root}\/lib\/.+\.rb)/i
|
13
|
+
]
|
14
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ar_schema'
|
3
|
+
|
4
|
+
ARSchema.connect!
|
5
|
+
|
6
|
+
describe "Integration with ActiveRecord" do
|
7
|
+
before(:each) do
|
8
|
+
ActiveRecord::Base.connection.execute("DELETE FROM categories")
|
9
|
+
ActiveRecord::Base.connection.execute("DELETE FROM products")
|
10
|
+
end
|
11
|
+
context "configuration defination" do
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
Object.send(:remove_const, :Product) rescue nil
|
15
|
+
klass = Class.new(ActiveRecord::Base)
|
16
|
+
Object.const_set(:Product,klass)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have class method for translation configuration" do
|
20
|
+
Product.class_eval do
|
21
|
+
include Lolita::Translation
|
22
|
+
end
|
23
|
+
|
24
|
+
Product.should.respond_to?(:translations)
|
25
|
+
Product.should.respond_to?(:translate)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should create configuration when class is loaded with field names to translate" do
|
29
|
+
Product.class_eval do
|
30
|
+
include Lolita::Translation
|
31
|
+
translate :name, :description
|
32
|
+
end
|
33
|
+
Product.translations_configuration.should be_kind_of(Lolita::Translation::Configuration)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should accept block and yield configuration" do
|
37
|
+
block_called = false
|
38
|
+
Product.class_eval do
|
39
|
+
include Lolita::Translation
|
40
|
+
translate :name, :description do |conf|
|
41
|
+
block_called = true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
block_called.should be_true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "record" do
|
49
|
+
let(:category){Category.create(:name => "category_name", :default_locale => "en")}
|
50
|
+
|
51
|
+
before(:each) do
|
52
|
+
Object.send(:remove_const, :Category) rescue nil
|
53
|
+
klass = Class.new(ActiveRecord::Base)
|
54
|
+
Object.const_set(:Category,klass)
|
55
|
+
Category.class_eval do
|
56
|
+
include Lolita::Translation
|
57
|
+
translate :name
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "validation should fail when no location is given, but class accepts translation locale" do
|
62
|
+
category = Category.create(:name => Faker::Name.first_name, :default_locale => "")
|
63
|
+
category.errors.keys.should include(:default_locale)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have default locale" do
|
67
|
+
category = Category.create(:name => Faker::Name.first_name, :default_locale => "en")
|
68
|
+
I18n.default_locale = :lv
|
69
|
+
category.original_locale.should eq("en")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should have translations" do
|
73
|
+
category.translations.should be_empty
|
74
|
+
category.update_attributes(:name => "updated",:translations_attributes => [{:name => "translation-lv", :locale => "lv"}])
|
75
|
+
category.errors.should be_empty
|
76
|
+
category.translations.reload.should have(1).item
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return translatable attribute in current locale" do
|
80
|
+
I18n.default_locale = :lv
|
81
|
+
I18n.locale = :lv
|
82
|
+
category.name.should eq("category_name")
|
83
|
+
I18n.locale = :en
|
84
|
+
category.name.should eq("category_name")
|
85
|
+
category.update_attributes(:name => "updated",:translations_attributes => [{:name => "translation-lv", :locale => "lv"}])
|
86
|
+
I18n.locale = :lv
|
87
|
+
category.name.should eq("translation-lv")
|
88
|
+
I18n.locale = :ru
|
89
|
+
category.name.should eq("updated")
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should switch attribute to different locale" do
|
93
|
+
category.name.should eq("category_name")
|
94
|
+
category.update_attributes(:translations_attributes => [{:name => "translation-lv", :locale => "lv"}])
|
95
|
+
category.name.in(:lv).should eq("translation-lv")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "saving" do
|
100
|
+
let(:category){Category.create(:name => "category_name", :default_locale => :en)}
|
101
|
+
let(:product){ Product.create(:name => "product_name", :description => "product_description") }
|
102
|
+
|
103
|
+
before(:each) do
|
104
|
+
I18n.locale = :en
|
105
|
+
I18n.default_locale = :lv
|
106
|
+
Object.send(:remove_const, :Category) rescue nil
|
107
|
+
Object.send(:remove_const, :Product) rescue nil
|
108
|
+
klass = Class.new(ActiveRecord::Base)
|
109
|
+
Object.const_set(:Category,klass)
|
110
|
+
product_klass = Class.new(ActiveRecord::Base)
|
111
|
+
Object.const_set(:Product,product_klass)
|
112
|
+
Category.class_eval do
|
113
|
+
include Lolita::Translation
|
114
|
+
translate :name
|
115
|
+
end
|
116
|
+
Product.class_eval do
|
117
|
+
include Lolita::Translation
|
118
|
+
translate :name, :description
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should create translations for object" do
|
123
|
+
new_cat = Category.create({
|
124
|
+
:name => "cat_name",
|
125
|
+
:original_locale => :en,
|
126
|
+
:translations_attributes => [
|
127
|
+
{:name => "translation-lv", :locale => "lv"},
|
128
|
+
{:name => "translation-fr", :locale => "fr"}
|
129
|
+
]
|
130
|
+
})
|
131
|
+
new_cat.errors.should be_empty
|
132
|
+
new_cat.translations.should have(2).items
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should save translation as nested attributes" do
|
136
|
+
category.translations.should be_empty
|
137
|
+
category.update_attributes(:translations_attributes => [
|
138
|
+
{:name => "translation-lv", :locale => "lv"},
|
139
|
+
{:name => "translation-fr", :locale => "fr"}
|
140
|
+
])
|
141
|
+
category.translations.reload
|
142
|
+
category.translations.should have(2).items
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should save locale for record if it accepts it" do
|
146
|
+
I18n.locale = :lv
|
147
|
+
category.original_locale.should eq(:en)
|
148
|
+
product.original_locale.should eq(:lv)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should not save translation for record default locale" do
|
152
|
+
category.translations.should be_empty
|
153
|
+
category.update_attributes(:translations_attributes => [
|
154
|
+
{ :name => "translation2-lv", :locale => "lv"},
|
155
|
+
{ :name => "translation2-en", :locale => "en"}
|
156
|
+
])
|
157
|
+
category.errors.keys.should include(:"translations.locale")
|
158
|
+
end
|
159
|
+
|
160
|
+
it "translation record should be associated with original record" do
|
161
|
+
transl1 = CategoryTranslation.new(:name => "translation-lv", :locale => "lv")
|
162
|
+
transl1.category = category
|
163
|
+
transl1.save
|
164
|
+
transl1.errors.should be_empty
|
165
|
+
transl2 = CategoryTranslation.create(:name => "translation-fr", :locale => "fr")
|
166
|
+
transl2.update_attributes(:name => "updated-translation-fr")
|
167
|
+
transl2.errors.keys.should include(:"category")
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should validate that locale is presented" do
|
171
|
+
transl1 = CategoryTranslation.new(:name => "translation-lv")
|
172
|
+
transl1.category = category
|
173
|
+
transl1.save
|
174
|
+
transl1.errors.keys.should eq([:"locale"])
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should validate that locale is unique for each original record" do
|
178
|
+
transl1 = category.translations.create(:name => "translation-lv", :locale => "lv")
|
179
|
+
transl2 = category.translations.create(:name => "translation-lv", :locale => "lv")
|
180
|
+
transl1.errors.should be_empty
|
181
|
+
transl2.errors.keys.should eq([:"locale"])
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should use default locale for records without default locale field" do
|
185
|
+
product.update_attributes(:translations_attributes => [
|
186
|
+
{ :name => "product_name-ru", :locale => "ru"}
|
187
|
+
])
|
188
|
+
product.name.should eq("product_name")
|
189
|
+
I18n.locale = :ru
|
190
|
+
product.name.should eq("product_name-ru")
|
191
|
+
I18n.locale = :en
|
192
|
+
product.name.should eq("product_name")
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context "migrating" do
|
197
|
+
before(:each) do
|
198
|
+
Object.send(:remove_const,:Comment) rescue nil
|
199
|
+
c_class = Class.new(ActiveRecord::Base)
|
200
|
+
Object.const_set(:Comment,c_class)
|
201
|
+
c_class.class_eval do
|
202
|
+
include Lolita::Translation
|
203
|
+
translate :body
|
204
|
+
end
|
205
|
+
ActiveRecord::Base.connection.execute("DROP TABLE comments_translations") rescue nil
|
206
|
+
end
|
207
|
+
|
208
|
+
after(:each) do
|
209
|
+
Object.send(:remove_const,:Comment) rescue nil
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should sync translation table through migrations" do
|
213
|
+
ActiveRecord::Base.connection.tables.should_not include("comments_translations")
|
214
|
+
Comment.sync_translation_table!
|
215
|
+
ActiveRecord::Base.connection.tables.should include("comments_translations")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|