translatable_ar 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -26,40 +26,50 @@ class TranslatableAR
26
26
  @translatable_ar_attributes << attribute
27
27
  @translatable_ar_attributes.uniq!
28
28
  end
29
-
30
- def define_translatable_ar_methods(attribute)
31
- serialize attribute, TranslatableAR.coder
29
+
30
+ def define_translatable_ar_methods(attribute)
31
+ serialize "#{attribute}_i18n", TranslatableAR.coder_or_default_object
32
32
  class_eval do
33
- define_translatable_ar_collection(attribute)
34
33
  define_translatable_ar_writer(attribute)
35
34
  define_translatable_ar_reader(attribute)
35
+ define_translatable_ar_changed?(attribute)
36
36
  end
37
37
  end
38
38
 
39
- def define_translatable_ar_collection(attribute)
40
- define_method("#{attribute}_translations") do
41
- self["#{attribute}"] ||= {}
42
- end
43
- end
44
-
45
39
  def define_translatable_ar_reader(attribute)
46
40
  define_method("#{attribute}") do
47
- send("#{attribute}_translations")[I18n.locale.to_s]
41
+ if respond_to?("#{attribute}_i18n")
42
+ send("#{attribute}_i18n")[I18n.locale.to_s]
43
+ else
44
+ super()
45
+ end
48
46
  end
49
47
  end
50
48
 
51
49
  def define_translatable_ar_writer(attribute)
52
50
  define_method("#{attribute}=") do |value|
53
- if value.is_a?(Hash)
54
- translations = value
51
+ if respond_to?("#{attribute}_i18n")
52
+ if value.is_a?(Hash)
53
+ send("#{attribute}_i18n=", value)
54
+ else
55
+ send("#{attribute}_i18n")[I18n.locale.to_s] = value
56
+ end
55
57
  else
56
- translations = send("#{attribute}_translations")
57
- translations[I18n.locale.to_s] = value
58
+ super(value)
58
59
  end
59
- super(translations)
60
60
  end
61
61
  end
62
-
62
+
63
+ def define_translatable_ar_changed?(attribute)
64
+ define_method("#{attribute}_changed?") do |value|
65
+ if respond_to?("#{attribute}_i18n")
66
+ send("#{attribute}_i18n_changed?")
67
+ else
68
+ super(value)
69
+ end
70
+ end
71
+ end
72
+
63
73
  end
64
74
  end
65
75
  end
data/lib/railtie.rb CHANGED
@@ -26,12 +26,43 @@ class TranslatableAr < Rails::Railtie
26
26
  end
27
27
 
28
28
  def create_migration_file
29
- Rails.application.eager_load! # load models
30
- migration_template template_path, 'db/migrate/setup_translatable_ar.rb'
29
+ Rails.application.eager_load! # trigger translates method call in models
30
+ time = Time.now.utc.strftime("%Y%m%d%H%M%S")
31
+
32
+ migration_template 'setup.rb', "db/migrate/setup_translatable_ar_#{time}.rb"
33
+ end
34
+
35
+ def models
36
+ models = []
37
+ TranslatableAR.models.each do |model|
38
+ model.translatable_ar_attributes.each do |attribute|
39
+ if model.columns_hash["#{attribute}_i18n"].nil?
40
+ models << model
41
+ end
42
+ end
43
+ end
44
+ models.uniq!
45
+ end
46
+
47
+ def attributes
48
+ attributes = []
49
+ attribute_struct = Struct.new(:name, :model)
50
+ TranslatableAR.models.each do |model|
51
+ model.translatable_ar_attributes.each do |attribute|
52
+ if model.columns_hash["#{attribute}_i18n"].nil?
53
+ attributes << attribute_struct.new(attribute, model)
54
+ end
55
+ end
56
+ end
57
+ attributes
58
+ end
59
+
60
+ def column_type
61
+ uses_hstore? ? :hstore : :text
31
62
  end
32
63
 
33
- def template_path
34
- TranslatableAR.uses_hstore? ? 'hstore.rb' : 'text.rb'
64
+ def uses_hstore?
65
+ TranslatableAR.uses_hstore?
35
66
  end
36
67
 
37
68
  end
@@ -0,0 +1,43 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration
2
+
3
+ def up
4
+
5
+ <% if uses_hstore? -%>
6
+ execute "CREATE EXTENSION IF NOT EXISTS hstore"
7
+ <% end -%>
8
+
9
+ <% attributes.each do |attribute| -%>
10
+ add_column :<%= attribute.model.table_name %>, :<%= attribute.name %>_i18n, :<%= column_type %>
11
+ <% end -%>
12
+
13
+ <% if uses_hstore?
14
+ attributes.each do |attribute| -%>
15
+ add_hstore_index :<%= attribute.model.table_name %>, :<%= attribute.name %>_i18n
16
+ <% end
17
+ end-%>
18
+
19
+ <% models.each do |model| -%>
20
+ puts "Preparing existing <%= model.to_s %> objects ..."
21
+ <%= model.to_s %>.reset_column_information
22
+ <%= model.to_s %>.all.each do |object|
23
+ <% attributes.select{|a| a.model == model}.each do |attribute| -%>
24
+ object.<%=attribute.name%> = object[:<%=attribute.name%>]
25
+ <% end -%>
26
+ object.save
27
+ end
28
+ <% end -%>
29
+ end
30
+
31
+ def down
32
+ <% attributes.each do |attribute| -%>
33
+ remove_column :<%= attribute.model.table_name %>, :<%= attribute.name %>_i18n
34
+ <% end -%>
35
+
36
+ <% if uses_hstore?
37
+ attributes.each do |attribute| -%>
38
+ remove_hstore_index :<%= attribute.model.table_name %>, :<%= attribute.name %>_i18n
39
+ <% end
40
+ end-%>
41
+ end
42
+
43
+ end
@@ -1,15 +1,18 @@
1
1
  class TranslatableAR
2
2
 
3
3
  class << self
4
- attr_accessor :models, :coder
5
- def coder
6
- @coder ||= Object # Use ActiveRecord's default serializer class
4
+ attr_accessor :models, :coder_or_default_object
5
+ def coder_or_default_object
6
+ @coder_or_default_object ||= Hash
7
7
  end
8
8
  def models
9
9
  @models ||= []
10
10
  end
11
11
  def uses_hstore?
12
- @coder == ActiveRecord::Coders::Hstore rescue false
12
+ @coder_or_default_object == ActiveRecord::Coders::Hstore rescue false
13
+ end
14
+ def use_hstore!
15
+ @coder_or_default_object = ActiveRecord::Coders::Hstore
13
16
  end
14
17
  end
15
18
 
@@ -6,37 +6,38 @@ class ProductTest < ActiveSupport::TestCase
6
6
 
7
7
  test "build with nested locale values" do
8
8
  p = Product.new(:name => {'en' => 'Chair', 'da' => 'Stol'}, image_url: '/image1.png')
9
- assert_equal 'Chair', p.name_translations['en']
10
- assert_equal 'Stol', p.name_translations['da']
9
+ assert_equal 'Chair', p.name_i18n['en']
10
+ assert_equal 'Stol', p.name_i18n['da']
11
11
  assert_equal '/image1.png', p.image_url
12
12
  end
13
13
 
14
14
  test "build with default locale" do
15
15
  p = Product.new(name: 'Table', image_url: '/image1.png')
16
16
  assert_equal('Table', p.name)
17
- assert_equal({'en' => 'Table'}, p.name_translations)
17
+ assert_equal({'en' => 'Table'}, p.name_i18n)
18
18
  assert_equal '/image1.png', p.image_url
19
19
  end
20
20
 
21
21
  test "create with nested locale values" do
22
- p = Product.create(:name => {'en' => 'Chair', 'da' => 'Stol'}, image_url: '/image1.png')
23
- assert_equal 'Chair', p.name_translations['en']
24
- assert_equal 'Stol', p.name_translations['da']
22
+ p = Product.create(:name => {'en' => 'Chair', 'da' => 'Stol'}, image_url: '/image1.png', permalink: 'asd')
23
+ assert_equal 'Chair', p.name_i18n['en']
24
+ assert_equal 'Stol', p.name_i18n['da']
25
25
  assert_equal '/image1.png', p.image_url
26
+ assert_equal 1, Product.count
26
27
  end
27
28
 
28
29
  test "create with default locale" do
29
30
  p = Product.create(name: 'Table', image_url: '/image1.png')
30
31
  assert_equal 'Table', p.name
31
- assert_equal({'en' => 'Table'}, p.name_translations)
32
+ assert_equal({'en' => 'Table'}, p.name_i18n)
32
33
  assert_equal '/image1.png', p.image_url
33
34
  end
34
35
 
35
36
  test "update with nested locale values" do
36
37
  p = Product.new
37
38
  p.update_attributes(:name => {'en' => 'Chair', 'da' => 'Stol'}, image_url: '/image1.png')
38
- assert_equal 'Chair', p.name_translations['en']
39
- assert_equal 'Stol', p.name_translations['da']
39
+ assert_equal 'Chair', p.name_i18n['en']
40
+ assert_equal 'Stol', p.name_i18n['da']
40
41
  assert_equal '/image1.png', p.image_url
41
42
  end
42
43
 
@@ -44,7 +45,7 @@ class ProductTest < ActiveSupport::TestCase
44
45
  p = Product.new
45
46
  p.update_attributes(name: 'Table', image_url: '/image1.png')
46
47
  assert_equal 'Table', p.name
47
- assert_equal({'en' => 'Table'}, p.name_translations)
48
+ assert_equal({'en' => 'Table'}, p.name_i18n)
48
49
  assert_equal '/image1.png', p.image_url
49
50
  end
50
51
 
@@ -62,14 +63,14 @@ class ProductTest < ActiveSupport::TestCase
62
63
  p.name = 'Bord'
63
64
 
64
65
  assert_equal 'Bord', p.name
65
- assert_equal({'en' => 'Table', 'da' => 'Bord'}, p.name_translations)
66
+ assert_equal({'en' => 'Table', 'da' => 'Bord'}, p.name_i18n)
66
67
 
67
68
  p.save
68
69
 
69
70
  I18n.locale = :en
70
71
 
71
72
  assert_equal 'Table', p.name
72
- assert_equal({'en' => 'Table', 'da' => 'Bord'}, p.name_translations)
73
+ assert_equal({'en' => 'Table', 'da' => 'Bord'}, p.name_i18n)
73
74
 
74
75
  end
75
76
 
@@ -78,8 +79,8 @@ class ProductTest < ActiveSupport::TestCase
78
79
  test "build from collection with nested locale values" do
79
80
  c = Category.create(name: 'Furniture')
80
81
  p = c.products.build(:name => {'en' => 'Chair', 'da' => 'Stol'}, image_url: '/image1.png')
81
- assert_equal 'Chair', p.name_translations['en']
82
- assert_equal 'Stol', p.name_translations['da']
82
+ assert_equal 'Chair', p.name_i18n['en']
83
+ assert_equal 'Stol', p.name_i18n['da']
83
84
  assert_equal '/image1.png', p.image_url
84
85
  end
85
86
 
@@ -87,15 +88,15 @@ class ProductTest < ActiveSupport::TestCase
87
88
  c = Category.create(name: 'Furniture')
88
89
  p = c.products.build(name: 'Table', image_url: '/image1.png')
89
90
  assert_equal('Table', p.name)
90
- assert_equal({'en' => 'Table'}, p.name_translations)
91
+ assert_equal({'en' => 'Table'}, p.name_i18n)
91
92
  assert_equal '/image1.png', p.image_url
92
93
  end
93
94
 
94
95
  test "create from collection with nested locale values" do
95
96
  c = Category.create(name: 'Furniture')
96
97
  p = c.products.create(:name => {'en' => 'Chair', 'da' => 'Stol'}, image_url: '/image1.png')
97
- assert_equal 'Chair', p.name_translations['en']
98
- assert_equal 'Stol', p.name_translations['da']
98
+ assert_equal 'Chair', p.name_i18n['en']
99
+ assert_equal 'Stol', p.name_i18n['da']
99
100
  assert_equal '/image1.png', p.image_url
100
101
  end
101
102
 
@@ -103,7 +104,7 @@ class ProductTest < ActiveSupport::TestCase
103
104
  c = Category.create(name: 'Furniture')
104
105
  p = c.products.create(name: 'Table', image_url: '/image1.png')
105
106
  assert_equal 'Table', p.name
106
- assert_equal({'en' => 'Table'}, p.name_translations)
107
+ assert_equal({'en' => 'Table'}, p.name_i18n)
107
108
  assert_equal '/image1.png', p.image_url
108
109
  end
109
110
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: translatable_ar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-08 00:00:00.000000000 Z
12
+ date: 2013-04-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -27,8 +27,7 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
- description: No joins. No locale columns. Attribute translations are saved in-column
31
- as a serialized hash.
30
+ description: Translations are saved in-column as a serialized hash or using HStore.
32
31
  email: kasperbn@gmail.com
33
32
  executables: []
34
33
  extensions: []
@@ -36,8 +35,7 @@ extra_rdoc_files: []
36
35
  files:
37
36
  - lib/active_record_methods.rb
38
37
  - lib/railtie.rb
39
- - lib/templates/hstore.rb
40
- - lib/templates/text.rb
38
+ - lib/templates/setup.rb
41
39
  - lib/translatable_ar.rb
42
40
  - lib/translatable_ar_class.rb
43
41
  - test/rails_3.2.11/test/unit/product_test.rb
@@ -62,9 +60,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
60
  version: '0'
63
61
  requirements: []
64
62
  rubyforge_project:
65
- rubygems_version: 1.8.24
63
+ rubygems_version: 1.8.25
66
64
  signing_key:
67
65
  specification_version: 3
68
- summary: Less painful i18n for your active record models
66
+ summary: i18n for your active record models with HStore / serialized attribute
69
67
  test_files:
70
68
  - test/rails_3.2.11/test/unit/product_test.rb
@@ -1,72 +0,0 @@
1
- class SetupTranslatableAr < ActiveRecord::Migration
2
-
3
- def up
4
- <% TranslatableAR.models.each do |model| -%>
5
- <% model.translatable_ar_attributes.each do |attribute| -%>
6
- add_column :<%= model.table_name %>, :<%= attribute %>_i18n_temp, :hstore
7
- <% end -%>
8
- <% end -%>
9
- <% TranslatableAR.models.each do |model| -%>
10
-
11
- <%= model.to_s %>.translates <%= model.translatable_ar_attributes.map {|a| ":#{a}_i18n_temp" }.join(', ') %>
12
- <%= model.to_s %>.all.each do |object|
13
- <% model.translatable_ar_attributes.each do |attribute| -%>
14
- if object[:<%=attribute%>].is_a? Hash
15
- object.<%=attribute%>_i18n_temp = object[:<%=attribute%>]
16
- else
17
- object.<%=attribute%>_i18n_temp = {'<%= I18n.locale%>' => object[:<%=attribute%>]}
18
- end
19
- <% end -%>
20
- object.save if object.changed?
21
- end
22
- <% end -%>
23
- <% TranslatableAR.models.each do |model| -%>
24
- <% model.translatable_ar_attributes.each do |attribute| -%>
25
- remove_column :<%= model.table_name %>, :<%= attribute %>
26
- rename_column :<%= model.table_name %>, :<%= attribute%>_i18n_temp, :<%= attribute %>
27
- <% end -%>
28
- <% end -%>
29
-
30
- <% TranslatableAR.models.each do |model| -%>
31
- <% model.translatable_ar_attributes.each do |attribute| -%>
32
- # execute "CREATE INDEX <%= model.table_name%>_gin_<%= attribute %> ON <%= model.table_name %> USING GIN(<%= attribute %>);"
33
- <% end -%>
34
- <% end -%>
35
- end
36
-
37
- def down
38
- <% TranslatableAR.models.each do |model| -%>
39
- <% model.translatable_ar_attributes.each do |attribute| -%>
40
- add_column :<%= model.table_name %>, :<%= attribute %>_i18n_temp, :<%= model.columns_hash[attribute.to_s].type %>
41
- <% end -%>
42
- <% end -%>
43
- <% TranslatableAR.models.each do |model| -%>
44
-
45
- <%= model.to_s %>.translates <%= model.translatable_ar_attributes.map {|a| ":#{a}_i18n_temp" }.join(', ') %>
46
- <%= model.to_s %>.all.each do |object|
47
- <% model.translatable_ar_attributes.each do |attribute| -%>
48
- if object[:<%=attribute%>].is_a? Hash
49
- object.<%=attribute%>_i18n_temp = object[:<%=attribute%>]['<%= I18n.locale%>']
50
- else
51
- object.<%=attribute%>_i18n_temp = object[:<%=attribute%>]
52
- end
53
- <% end -%>
54
- object.save if object.changed?
55
- end
56
- <% end -%>
57
-
58
- <% TranslatableAR.models.each do |model| -%>
59
- <% model.translatable_ar_attributes.each do |attribute| -%>
60
- execute "DROP INDEX <%= model.table_name%>_gin_<%= attribute %>;"
61
- <% end -%>
62
- <% end -%>
63
-
64
- <% TranslatableAR.models.each do |model| -%>
65
- <% model.translatable_ar_attributes.each do |attribute| -%>
66
- remove_column :<%= model.table_name %>, :<%= attribute %>
67
- rename_column :<%= model.table_name %>, :<%= attribute%>_i18n_temp, :<%= attribute %>
68
- <% end -%>
69
- <% end -%>
70
- end
71
-
72
- end
@@ -1,53 +0,0 @@
1
- class SetupTranslatableAr < ActiveRecord::Migration
2
-
3
- def up
4
- <% TranslatableAR.models.each do |model| -%>
5
- <% model.translatable_ar_attributes.each do |attribute| -%>
6
- add_column :<%= model.table_name %>, :<%= attribute %>_i18n_temp, :text
7
- <% end -%>
8
- <% end -%>
9
- <% TranslatableAR.models.each do |model| -%>
10
-
11
- <%= model.to_s %>.translates <%= model.translatable_ar_attributes.map {|a| ":#{a}_i18n_temp" }.join(', ') %>
12
- <%= model.to_s %>.all.each do |object|
13
- <% model.translatable_ar_attributes.each do |attribute| -%>
14
- if object[:<%=attribute%>].is_a? Hash
15
- object.<%=attribute%>_i18n_temp = object[:<%=attribute%>]
16
- else
17
- object.<%=attribute%>_i18n_temp = {'<%= I18n.default_locale%>' => object[:<%=attribute%>]}
18
- end
19
- <% end -%>
20
- object.save if object.changed?
21
- end
22
- <% end -%>
23
- <% TranslatableAR.models.each do |model| -%>
24
- <% model.translatable_ar_attributes.each do |attribute| -%>
25
- remove_column :<%= model.table_name %>, :<%= attribute %>
26
- rename_column :<%= model.table_name %>, :<%= attribute%>_i18n_temp, :<%= attribute %>
27
- <% end -%>
28
- <% end -%>
29
- end
30
-
31
- def down
32
- <% TranslatableAR.models.each do |model| -%>
33
- <% model.translatable_ar_attributes.each do |attribute| -%>
34
- add_column :<%= model.table_name %>, :<%= attribute %>_i18n_temp, :<%= model.columns_hash[attribute.to_s].type %>
35
- <% end -%>
36
- <% end -%>
37
- <% TranslatableAR.models.each do |model| -%>
38
-
39
- <%= model.to_s %>.all.each do |object|
40
- <% model.translatable_ar_attributes.each do |attribute| -%>
41
- object.<%=attribute%>_i18n_temp = object[:<%=attribute%>]['<%= I18n.default_locale%>']
42
- <% end -%>
43
- object.save if object.changed?
44
- <% end -%>
45
- <% TranslatableAR.models.each do |model| -%>
46
- <% model.translatable_ar_attributes.each do |attribute| -%>
47
- remove_column :<%= model.table_name %>, :<%= attribute %>
48
- rename_column :<%= model.table_name %>, :<%= attribute%>_i18n_temp, :<%= attribute %>
49
- <% end -%>
50
- <% end -%>
51
- end
52
-
53
- end