translatable 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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: