translatable 0.1.1 → 0.1.2

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/README.rdoc CHANGED
@@ -19,9 +19,67 @@ If there is no translation available, you will get nil.
19
19
 
20
20
  Check out the examples below.
21
21
 
22
+ == How to use?
23
+
24
+ Just define inside of your model `translatable` with block.
25
+ Block accepts following methods:
26
+
27
+ translatable *args
28
+ Params:
29
+ first - Here should be specified an attribute that will be translated.
30
+ second - Define here a hash that will be later provided for validation to model.
31
+
32
+ This method may be called multiple times.
33
+ Examples:
34
+ translatable :title, :presence => true, :uniqueness => true
35
+ translatable :content, :presence => true
36
+ translatable :notes
37
+
38
+ translatable_model model_name
39
+ Params:
40
+ model_name - Define the model name here if it is different from following "Translatable<CURRENT_MODEL>".
41
+ For News model, TranslatableNews will be used as the one that keeping translations. It can be defined
42
+ in a three ways: as constant, string or symbol.
43
+ Examples:
44
+ translatable_model TranslatedNews
45
+ OR
46
+ translatable_model "TranslatedNews"
47
+ OR
48
+ translatable_model :TranslatedNews
49
+
50
+ translatable_origin origin_key
51
+ Params:
52
+ origin_key - This key will be used to define the the relations for translations model.
53
+ By default it will be :origin. Translations model should also have such attribute defined.
54
+
55
+ This value will also be used for validation, as its presence is compulsory for translations model.
56
+ Examples:
57
+ translatable_origin :message
58
+ OR
59
+ translatable_origin :post
60
+
61
+ translatable_locale locale_attr
62
+ Params:
63
+ locale_attr - This key will be used to define the attribute that is keeping the locale of the translation.
64
+ By default it will be :locale. Translations model should also have such attribute defined.
65
+
66
+ This value will also be used for validation, as its presence is compulsory for translations model.
67
+ Examples:
68
+ translatable_locale :language
69
+ OR
70
+ translatable_locale :lang
71
+
72
+ == Now to create the translations?
73
+
74
+ They can be created in two different ways:
75
+
76
+ First is using the original model. Just provide the translations attributes within `translations_attributes` array.
77
+ Second - just create a new translation as if it would be independent model.
78
+ For details see Examples below.
79
+
22
80
  == Examples
23
81
 
24
- Migrations:
82
+ Migrations:
25
83
 
26
84
  class CreateTables < ActiveRecord::Migration
27
85
  def up
@@ -54,16 +112,13 @@ Check out the examples below.
54
112
  end
55
113
  end
56
114
 
57
- Models:
115
+ Models:
58
116
 
59
117
  class Author < ActiveRecord::Base
60
118
  validates :name, :presence => true
61
119
  end
62
120
 
63
121
  class TranslatableNews < ActiveRecord::Base
64
- validates :title, :content, :presence => true
65
- validates :title, :uniqueness => true
66
-
67
122
  attr_accessible :title, :content
68
123
  end
69
124
 
@@ -71,19 +126,19 @@ Check out the examples below.
71
126
 
72
127
  belongs_to :author
73
128
 
74
- is :translatable do
75
- translatable :title
76
- translatable :content
77
- translatable_model TranslatedNews
129
+ translatable do
130
+ translatable :title, :presence => true, :uniqueness => true
131
+ translatable :content, :presence => true
132
+ translatable_model "TranslatedNews"
78
133
  translatable_origin :origin_id
79
134
  end
80
135
 
81
136
  attr_accessible :author_id, :author
82
137
  end
83
138
 
84
- An example of application:
139
+ An example of application:
85
140
 
86
- news = News.create :translations => [{title: "Resent News", content: "That is where the text goes", locale: "en"}]
141
+ news = News.create :translations_attributes => [{title: "Resent News", content: "That is where the text goes", locale: "en"}]
87
142
  news.translations.create title: "Заголовок", content: "Содержание",locale: "ru"
88
143
 
89
144
  news.content
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
data/lib/translatable.rb CHANGED
@@ -12,10 +12,7 @@ module ActiveRecord
12
12
  # validates :name, :presence => true
13
13
  # end
14
14
  #
15
- # class TranslatableNews < ActiveRecord::Base
16
- # validates :title, :content, :presence => true
17
- # validates :title, :uniqueness => true
18
- #
15
+ # class TranslatableNews < ActiveRecord::Base #
19
16
  # attr_accessible :title, :content
20
17
  # end
21
18
  #
@@ -23,10 +20,10 @@ module ActiveRecord
23
20
  #
24
21
  # belongs_to :author
25
22
  #
26
- # is :translatable do
27
- # translatable :title
28
- # translatable :content
29
- # translatable_model TranslatedNews
23
+ # translatable do
24
+ # translatable :title, :presence => true, :uniqueness => true
25
+ # translatable :content, :presence => true
26
+ # translatable_model "TranslatedNews"
30
27
  # translatable_origin :origin_id
31
28
  # end
32
29
  #
@@ -176,11 +173,17 @@ module ActiveRecord
176
173
  def current_translation
177
174
  if translatable_locale_changed?
178
175
  @translatable_locale = ::I18n.locale.to_s
179
- @current_translation = translations.where(:#{@translatable[:locale]} => @translatable_locale).first
176
+ translatable_set_current
180
177
  end
181
178
  @current_translation
182
179
  end
183
180
  protected :current_translation
181
+
182
+
183
+ def translatable_set_current
184
+ @current_translation = translations.where(:#{@translatable[:locale]} => @translatable_locale).first
185
+ end
186
+ protected :translatable_set_current
184
187
  RUBY
185
188
  end
186
189
 
@@ -193,6 +196,14 @@ module ActiveRecord
193
196
 
194
197
  attr_accessible :#{@translatable[:locale]}, :#{@translatable[:origin]}_id
195
198
  RUBY
199
+
200
+ @translatable[:properties].each do |p|
201
+ if p.size > 1
202
+ @translatable[:model].module_eval <<-RUBY, __FILE__, __LINE__ + 1
203
+ validates :#{p.first}, #{p.last.inspect}
204
+ RUBY
205
+ end
206
+ end
196
207
  end
197
208
  end
198
209
 
data/test/news.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'active_record'
2
2
  require 'translatable'
3
3
 
4
- class CreateTables < ActiveRecord::Migration
4
+ class CreateNewsTables < ActiveRecord::Migration
5
5
  def up
6
6
  create_table(:authors) do |t|
7
7
  t.string :name, :null => false
@@ -32,7 +32,7 @@ class CreateTables < ActiveRecord::Migration
32
32
  end
33
33
  end
34
34
 
35
- CreateTables.migrate(:up)
35
+ CreateNewsTables.migrate(:up)
36
36
 
37
37
  class Author < ActiveRecord::Base
38
38
  validates :name, :presence => true
data/test/posts.rb ADDED
@@ -0,0 +1,66 @@
1
+ require 'active_record'
2
+ require 'translatable'
3
+
4
+ class CreatePostsTables < ActiveRecord::Migration
5
+ def up
6
+ create_table(:writers) do |t|
7
+ t.string :name, :null => false
8
+
9
+ t.timestamps
10
+ end
11
+
12
+ create_table(:translated_posts) do |t|
13
+ t.string :title, :null => false
14
+ t.string :content, :null => false
15
+ t.integer :post_id, :null => false
16
+ t.string :locale, :null => false, :limit => 2
17
+ t.integer :writer_id
18
+
19
+ t.timestamps
20
+ end
21
+
22
+ create_table(:posts) do |t|
23
+ t.integer :writer_id
24
+
25
+ t.timestamps
26
+ end
27
+ end
28
+
29
+ def down
30
+ drop_table(:writers)
31
+ drop_table(:translated_posts)
32
+ drop_table(:posts)
33
+ end
34
+ end
35
+
36
+ CreatePostsTables.migrate(:up)
37
+
38
+ class Author < ActiveRecord::Base
39
+ validates :name, :presence => true
40
+ end
41
+
42
+ class TranslatedPost < ActiveRecord::Base
43
+ attr_accessible :title, :content
44
+
45
+ before_create :duplicate_writer_id
46
+
47
+ protected
48
+
49
+ def duplicate_writer_id
50
+ self.writer_id = post.writer_id
51
+ end
52
+ end
53
+
54
+ class Post < ActiveRecord::Base
55
+
56
+ belongs_to :writer
57
+
58
+ translatable do
59
+ translatable :title, :presence => true, :uniqueness => true
60
+ translatable :content, :presence => true
61
+ translatable_model 'TranslatedPost'
62
+ translatable_origin :post
63
+ end
64
+
65
+ attr_accessible :writer_id, :writer
66
+ end
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'helper'
3
3
  require 'news'
4
+ require 'posts'
4
5
 
5
6
  class TestDmTranslatable < Test::Unit::TestCase
6
7
 
@@ -185,4 +186,36 @@ class TestDmTranslatable < Test::Unit::TestCase
185
186
  assert t.new_record?
186
187
  end
187
188
  end
189
+
190
+ def test_validations_are_defined
191
+ post = Post.create :translations_attributes => [{:title => "Заголовок",:content => "Содержание", :locale => "ru"},
192
+ {:title => "Resent Post", :content => "That is where the text goes", :locale => "en"}]
193
+ assert post.persisted?, "Message had errors: #{post.errors.inspect}"
194
+
195
+ post = Post.create :translations_attributes => [{:content => "Содержание", :locale => "ru"},
196
+ {:title => "Resent Post 2", :content => "That is where the text goes", :locale => "en"}]
197
+
198
+ assert post.new_record?, "Message had errors: #{post.errors.full_messages.inspect}"
199
+ assert_equal ["Translations title can't be blank"], post.errors.full_messages
200
+
201
+ post = Post.create :translations_attributes => [{:title => "Заголовок 2", :locale => "ru"},
202
+ {:title => "Resent Post 3", :content => "That is where the text goes", :locale => "en"}]
203
+
204
+ assert post.new_record?, "Message had errors: #{post.errors.full_messages.inspect}"
205
+ assert_equal ["Translations content can't be blank"], post.errors.full_messages
206
+
207
+ post = Post.create :translations_attributes => [{:title => "Заголовок", :content => "Содержание", :locale => "ru"},
208
+ {:title => "Resent Post 3", :content => "That is where the text goes", :locale => "en"}]
209
+
210
+ assert post.new_record?, "Message had errors: #{post.errors.full_messages.inspect}"
211
+ assert_equal ["Translations title has already been taken"], post.errors.full_messages
212
+ end
213
+
214
+ def test_origin_is_owerwrittent
215
+ post = Post.create :translations_attributes => [{:title => "Заголовок",:content => "Содержание", :locale => "ru"},
216
+ {:title => "Resent Post", :content => "That is where the text goes", :locale => "en"}]
217
+ assert post.persisted?, "Message had errors: #{post.errors.inspect}"
218
+
219
+ assert_equal post, post.translations.first.post
220
+ end
188
221
  end
data/translatable.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "translatable"
8
- s.version = "0.1.1"
8
+ s.version = "0.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["E-Max"]
12
- s.date = "2012-08-17"
12
+ s.date = "2012-08-18"
13
13
  s.description = "This game was build to make whole proccess of working with translation for DM to be almost invisble. That was THE AIM."
14
14
  s.email = "max@studentify.nl"
15
15
  s.extra_rdoc_files = [
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
29
29
  "lib/translatable.rb",
30
30
  "test/helper.rb",
31
31
  "test/news.rb",
32
+ "test/posts.rb",
32
33
  "test/support/active_record.rb",
33
34
  "test/support/database_cleaner.rb",
34
35
  "test/test_translatable.rb",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: translatable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-17 00:00:00.000000000Z
12
+ date: 2012-08-18 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &79558880 !ruby/object:Gem::Requirement
16
+ requirement: &86896860 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *79558880
24
+ version_requirements: *86896860
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: i18n
27
- requirement: &79558640 !ruby/object:Gem::Requirement
27
+ requirement: &86896620 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *79558640
35
+ version_requirements: *86896620
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: yard
38
- requirement: &79558400 !ruby/object:Gem::Requirement
38
+ requirement: &86896380 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *79558400
46
+ version_requirements: *86896380
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: jeweler
49
- requirement: &79558160 !ruby/object:Gem::Requirement
49
+ requirement: &86896140 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.6.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *79558160
57
+ version_requirements: *86896140
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: bundler
60
- requirement: &79557920 !ruby/object:Gem::Requirement
60
+ requirement: &86895900 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.0.0
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *79557920
68
+ version_requirements: *86895900
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: simplecov
71
- requirement: &79557680 !ruby/object:Gem::Requirement
71
+ requirement: &86895660 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.6.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *79557680
79
+ version_requirements: *86895660
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rcov
82
- requirement: &79557440 !ruby/object:Gem::Requirement
82
+ requirement: &86895420 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: 1.0.0
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *79557440
90
+ version_requirements: *86895420
91
91
  description: This game was build to make whole proccess of working with translation
92
92
  for DM to be almost invisble. That was THE AIM.
93
93
  email: max@studentify.nl
@@ -109,6 +109,7 @@ files:
109
109
  - lib/translatable.rb
110
110
  - test/helper.rb
111
111
  - test/news.rb
112
+ - test/posts.rb
112
113
  - test/support/active_record.rb
113
114
  - test/support/database_cleaner.rb
114
115
  - test/test_translatable.rb
@@ -128,7 +129,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
128
129
  version: '0'
129
130
  segments:
130
131
  - 0
131
- hash: 191627663
132
+ hash: -150355887
132
133
  required_rubygems_version: !ruby/object:Gem::Requirement
133
134
  none: false
134
135
  requirements: