translated_attributes 0.5.1

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/MIGRATION ADDED
@@ -0,0 +1,18 @@
1
+ class AddTranslations < ActiveRecord::Migration
2
+ def self.up
3
+ #you can remove the limit/null constrains
4
+ #this is simply my recommended way of setting things up (save + limits needed storage space)
5
+ create_table :translations do |t|
6
+ t.column :translatable_id, :integer, :null=>false
7
+ t.column :translatable_type, :string, :limit=>40, :null=>false
8
+ t.column :language, :string, :limit=>2, :null=>false
9
+ t.column :attribute, :string, :limit=>40, :null=>false
10
+ t.column :text, :text, :null=>false
11
+ end
12
+ add_index :translations, [:translatable_id, :translatable_type]
13
+ end
14
+
15
+ def self.down
16
+ drop_table :translations
17
+ end
18
+ end
data/README.markdown ADDED
@@ -0,0 +1,49 @@
1
+ Rails plugin/ActiveRecord gem that creates 'virtual' attributes, which can be added on the fly without overhead or migrations, while storing all the data in a never-changing translations table.
2
+ This keeps the attatched model light and allows to add/remove fields on the fly without migrations.
3
+
4
+ Validations work like normal with current field (e.g. title) or any translation (e.g. title_in_en)
5
+
6
+ Usage
7
+ =====
8
+ - As Rails plugin `script/plugin install git://github.com/grosser/translated_attributes.git`
9
+ - As gem `sudo gem install translated_attributes`
10
+ - execute MIGRATION
11
+
12
+ Adding attributes:
13
+ class Product < ActiveRecord::Base
14
+ translated_attributes :description, :title, :additional_info
15
+ end
16
+
17
+ Setting / getting
18
+ #getter
19
+ product.title -> 'Hello' #when I18n.locale is :en
20
+ product.title_in_fr -> 'Bonyour'
21
+ product.title_in_de -> 'Hallo'
22
+
23
+ #setter
24
+ product.title = 'Simple setting' #sets title_in_en when I18n.locale == :en
25
+ product.title_in_de = 'Spezifisches speichern'
26
+
27
+ #generic setter/getter
28
+ product.set_title('Specific setting', :en)
29
+ product.get_title(:en) -> 'Specific setting'
30
+
31
+ Usage with saving works exactly like normal saving, e.g. new/create/update_attributes...
32
+ Product.new(:title_in_en=>'Hello').save!
33
+ product.update_attribute(:title, 'Goodbye')
34
+
35
+ - Translations are stored on 'save'
36
+ - blank translations are NOT stored
37
+ - translations are accessable via .translations or as hash via .translated_attributes
38
+
39
+ Options
40
+ =======
41
+ translated_attributes :title, :heading,
42
+ :table_name => 'user_translations', #default is translations
43
+ :nil_to_blank => true, #return unfound translations as blank strings ('') instead of nil (default false),
44
+ :translatable_name => 'translated' #name of the associated translatable (Product has_many :translations a Translation belongs_to XXX), default is :translatable
45
+ Author
46
+ ======
47
+ [Michael Grosser](http://pragmatig.wordpress.com)
48
+ grosser.michael@gmail.com
49
+ Hereby placed under public domain, do what you want, just do not hold me accountable...
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ desc "Run all specs in spec directory"
2
+ task :default do
3
+ options = "--colour --format progress --loadby --reverse"
4
+ files = FileList['spec/**/*_spec.rb']
5
+ system("spec #{options} #{files}")
6
+ end
7
+
8
+ begin
9
+ project_name = 'translated_attributes'
10
+ require 'jeweler'
11
+ Jeweler::Tasks.new do |gem|
12
+ gem.name = project_name
13
+ gem.summary = "ActiveRecord/Rails simple translatable attributes"
14
+ gem.email = "grosser.michael@gmail.com"
15
+ gem.homepage = "http://github.com/grosser/#{project_name}"
16
+ gem.authors = ["Michael Grosser"]
17
+ gem.files += (FileList["{lib,spec}/**/*"] + FileList["VERSION"] + FileList["README.markdown"]).to_a.sort
18
+ gem.add_dependency ['activerecord']
19
+ gem.rubyforge_project = 'translated-attr'
20
+ end
21
+
22
+ # fake task so that rubyforge:release works
23
+ task :rdoc do
24
+ `mkdir rdoc`
25
+ `echo documentation is at http://github.com/grosser/#{project_name} > rdoc/README.rdoc`
26
+ end
27
+
28
+ Jeweler::RubyforgeTasks.new
29
+ rescue LoadError
30
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
31
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.1
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ #Needed to load when used as Rails plugin
2
+ require 'translated_attributes'
@@ -0,0 +1,152 @@
1
+ module TranslatedAttributes
2
+ module ClassMethods
3
+ # translated_attributes :title, :description, :table_name=>'my_translations'
4
+ def translated_attributes(*args)
5
+ #store options
6
+ cattr_accessor :translated_attributes_options
7
+ options = args.extract_options! || {}
8
+ self.translated_attributes_options = options.merge(:fields=>args.map(&:to_sym))
9
+
10
+ #create translations class
11
+ table_name = options[:table_name] || :translations
12
+ class_name = table_name.to_s.classify
13
+
14
+ associated = options[:translatable_name] || :translatable
15
+ begin
16
+ klass = Object.const_get(class_name)
17
+ rescue
18
+ klass = Class.new(ActiveRecord::Base)
19
+ Object.const_set(class_name, klass)
20
+ klass.set_table_name table_name
21
+ klass.belongs_to associated, :polymorphic => true
22
+ end
23
+
24
+ #set translations
25
+ has_many :translations, :as => associated, :dependent => :delete_all, :class_name=>klass.name
26
+
27
+ #include methods
28
+ include TranslatedAttributes::InstanceMethods
29
+ end
30
+ end
31
+
32
+ module InstanceMethods
33
+ def self.included(base)
34
+ fields = base.translated_attributes_options[:fields]
35
+ fields.each do |field|
36
+ base.class_eval <<-GETTER_AND_SETTER
37
+ def get_#{field}(locale=nil)
38
+ get_translated_attribute(locale, :#{field})
39
+ end
40
+
41
+ def set_#{field}(value, locale=I18n.locale)
42
+ set_translated_attribute(locale, :#{field}, value)
43
+ end
44
+
45
+ #generic aliases (and since e.g. title=(a,b) would not be possible)
46
+ alias #{field} get_#{field}
47
+ alias #{field}= set_#{field}
48
+ GETTER_AND_SETTER
49
+ end
50
+
51
+ base.after_save :store_translated_attributes
52
+ end
53
+
54
+ def get_translated_attribute(locale, field)
55
+ text = if locale
56
+ translated_attributes_for(locale)[field]
57
+ else
58
+ #try to find anything...
59
+ #current, english, anything else
60
+ found = translated_attributes_for(I18n.locale)[field] || translated_attributes_for(:en)[field]
61
+ if found
62
+ found
63
+ else
64
+ found = translated_attributes.detect{|locale, attributes| not attributes[field].blank?}
65
+ found ? found[1][field] : nil
66
+ end
67
+ end
68
+
69
+ if self.class.translated_attributes_options[:nil_to_blank]
70
+ text || ''
71
+ else
72
+ text
73
+ end
74
+ end
75
+
76
+ def set_translated_attribute(locale, field, value)
77
+ return if translated_attributes_for(locale)[field] == value
78
+ translated_attributes_for(locale)[field] = value
79
+ @translated_attributes_changed = true
80
+ end
81
+
82
+ def translated_attributes
83
+ merge_db_translations_with_instance_variable
84
+ @translated_attributes ||= {}.with_indifferent_access
85
+ end
86
+
87
+ def translated_attributes= hash
88
+ @db_translations_merged = true #do not overwrite what we set here
89
+ @translated_attributes_changed = true #store changes we made
90
+ @translated_attributes = hash.with_indifferent_access
91
+ end
92
+
93
+ def respond_to?(name, *args)
94
+ return true if parse_translated_attribute_method(name)
95
+ super
96
+ end
97
+
98
+ def method_missing(name, *args)
99
+ field, locale = parse_translated_attribute_method(name)
100
+ return super unless field
101
+ if name.to_s.include? '=' #is setter ?
102
+ send("set_#{field}", args[0], locale)
103
+ else
104
+ send("get_#{field}", locale)
105
+ end
106
+ end
107
+
108
+ protected
109
+
110
+ def store_translated_attributes
111
+ return true unless @translated_attributes_changed
112
+ translations.delete_all
113
+ @translated_attributes.each do |locale, attributes|
114
+ attributes.each do |attribute, value|
115
+ next if value.blank?
116
+ next unless self.class.translated_attributes_options[:fields].include? attribute.to_sym
117
+ translations.create!(:attribute=>attribute, :text=>value, :language=>locale)
118
+ end
119
+ end
120
+ @translated_attributes_changed = false
121
+ end
122
+
123
+ private
124
+
125
+ def merge_db_translations_with_instance_variable
126
+ return if new_record? or @db_translations_merged
127
+ @db_translations_merged = true
128
+ translations.all.each do |t|
129
+ translated_attributes_for(t.language)[t.attribute] = t.text
130
+ end
131
+ end
132
+
133
+ def parse_translated_attribute_method(name)
134
+ return false if name.to_s !~ /^([a-zA-Z_]+)_in_([a-z]{2})[=]?$/
135
+ field = $1; locale = $2
136
+ return false unless is_translated_attribute?(field)
137
+ return field, locale
138
+ end
139
+
140
+ def is_translated_attribute?(method_name)
141
+ fields = self.class.translated_attributes_options[:fields]
142
+ fields.include? method_name.sub('=','').to_sym
143
+ end
144
+
145
+ def translated_attributes_for(locale)
146
+ translated_attributes[locale] ||= {}.with_indifferent_access
147
+ translated_attributes[locale]
148
+ end
149
+ end
150
+ end
151
+
152
+ ActiveRecord::Base.send :extend, TranslatedAttributes::ClassMethods
@@ -0,0 +1,42 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe 'Integration' do
4
+ before do
5
+ Translation.delete_all
6
+ UserTranslation.delete_all
7
+ end
8
+
9
+ it "manages different translations appropriatly" do
10
+ User.create(:name_in_en=>'User1NameEn', :name_in_de=>'User1NameDe')
11
+ User.create(:name_in_en=>'User2NameEn', :name_in_fr=>'User2NameFr')
12
+ Product.create(:title=>'Product1TitleEn', :title_in_de=>'Product1TitleDe')
13
+
14
+ User.first.translated_attributes = {}
15
+ u = User.last
16
+ u.translated_attributes = {:fr=>{:name=>'User1NameFr'}}
17
+ u.save!
18
+
19
+ UserTranslation.count.should == 3
20
+ Translation.count.should == 2
21
+ User.last.name.should == 'User1NameFr'
22
+ end
23
+
24
+ it "cleans up translations" do
25
+ User.create!(:name=>'u1')
26
+ Product.create!(:title=>'p1',:description=>'d1')
27
+ Product.create!(:title=>'p2')
28
+
29
+ Translation.count.should == 3
30
+ UserTranslation.count.should == 1
31
+
32
+ Product.destroy_all
33
+
34
+ Translation.count.should == 0
35
+ UserTranslation.count.should == 1
36
+
37
+ User.destroy_all
38
+
39
+ Translation.count.should == 0
40
+ UserTranslation.count.should == 0
41
+ end
42
+ end
data/spec/models.rb ADDED
@@ -0,0 +1,31 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+ create_table :users do |t|
3
+ end
4
+
5
+ create_table :products do |t|
6
+ end
7
+
8
+ %w[translations user_translations].each do |table|
9
+ create_table table do |t|
10
+ t.integer :translatable_id, :null=>false
11
+ t.string :translatable_type, :limit=>40, :null=>false
12
+ t.string :language, :limit=>2, :null=>false
13
+ t.string :attribute, :limit=>40, :null=>false
14
+ t.text :text, :null=>false
15
+ end
16
+ end
17
+ end
18
+
19
+ #create model
20
+ class User < ActiveRecord::Base
21
+ translated_attributes :name, :table_name=>:user_translations, :nil_to_blank=>true
22
+ end
23
+
24
+ class Shop < ActiveRecord::Base
25
+ set_table_name :products
26
+ translated_attributes :shop_name
27
+ end
28
+
29
+ class Product < ActiveRecord::Base
30
+ translated_attributes :title, :description
31
+ end
@@ -0,0 +1,18 @@
1
+ # ---- requirements
2
+ require 'rubygems'
3
+ require 'spec'
4
+ require 'activerecord'
5
+
6
+ $LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__))
7
+
8
+ # ---- setup environment/plugin
9
+ ActiveRecord::Base.establish_connection({
10
+ :adapter => "sqlite3",
11
+ :database => ":memory:",
12
+ })
13
+
14
+ #ActiveRecord::Base.logger = Logger.new(STDOUT)
15
+
16
+ require File.expand_path("../init", File.dirname(__FILE__))
17
+
18
+ require 'spec/models'
@@ -0,0 +1,304 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe 'Translated attributes' do
4
+ before do
5
+ I18n.locale = :en
6
+ end
7
+
8
+ describe 'caching' do
9
+ it "is nil when nothing is set" do
10
+ Product.new.title.should == nil
11
+ Product.new.description.should == nil
12
+ end
13
+
14
+ it 'can be set' do
15
+ p = Product.new
16
+ p.title = 'abc'
17
+ p.title.should == 'abc'
18
+ end
19
+
20
+ it 'can be overwritten' do
21
+ p = Product.new
22
+ p.title = 'abc'
23
+ p.title = 'def'
24
+ p.title.should == 'def'
25
+ end
26
+
27
+ it "ca be unset" do
28
+ p = Product.new
29
+ p.title = 'abc'
30
+ p.title = nil
31
+ p.title.should == nil
32
+ end
33
+
34
+ it "sets the current language" do
35
+ p = Product.new
36
+ p.title = 'abc'
37
+ p.title_in_en.should == 'abc'
38
+ end
39
+
40
+ it "can be set in different languages" do
41
+ p = Product.new
42
+ p.title = 'abc'
43
+ p.title_in_de.should == nil
44
+ I18n.locale = :de
45
+ p.title = 'bcd'
46
+ p.title_in_de.should == 'bcd'
47
+ end
48
+
49
+ it "returns current language when current can be found" do
50
+ I18n.locale = :de
51
+ p = Product.new
52
+ p.title_in_de = 'abc'
53
+ p.title_in_en = 'def'
54
+ p.title.should == 'abc'
55
+ end
56
+
57
+ it "returns english translation when current cannot be found" do
58
+ I18n.locale = :de
59
+ p = Product.new
60
+ p.title_in_en = 'abc'
61
+ p.title.should == 'abc'
62
+ end
63
+
64
+ it "returns any translation when current and english cannot be found" do
65
+ I18n.locale = :fr
66
+ p = Product.new
67
+ p.title_in_de = 'abc'
68
+ p.title.should == 'abc'
69
+ end
70
+ end
71
+
72
+ describe 'storing' do
73
+ it "stores nothing when nothing was set" do
74
+ lambda{ Product.create! }.should_not change(Translation, :count)
75
+ Product.last.title.should == nil
76
+ end
77
+
78
+ it "stores column as translation on save" do
79
+ lambda{ Product.create!(:title=>'x') }.should change(Translation, :count).by(+1)
80
+ end
81
+
82
+ it "stores nothing when blank was set" do
83
+ lambda{ Product.create! :title=>' ' }.should_not change(Translation, :count)
84
+ Product.last.title.should == nil
85
+ end
86
+
87
+ it "creates no translation when validations fail" do
88
+ p = Product.new :title=>'xxx'
89
+ p.should_receive(:valid?).and_return false
90
+ lambda{ p.save }.should_not change(Translation, :count)
91
+ end
92
+
93
+ it "is stored after save" do
94
+ p = Product.create!(:title=>'1')
95
+ p.title = '2'
96
+ p.save!
97
+ Product.last.title.should == '2'
98
+ end
99
+
100
+ it "does not create unecessary translations on change" do
101
+ p = Product.create!(:title=>'1')
102
+ lambda{
103
+ p.title = '2'
104
+ p.save!
105
+ }.should_not change(Translation, :count)
106
+ end
107
+
108
+ it "does not update translations when nothing changed" do
109
+ p = Product.create!(:title=>'xx')
110
+ p.title = 'xx'
111
+ lambda{ p.save }.should_not change{Translation.last.id}
112
+ end
113
+
114
+ it "works through update_attribute" do
115
+ p = Product.create!(:title=>'xx', :description=>'dd')
116
+ p.update_attribute(:title, 'yy')
117
+ Product.last.title.should == 'yy'
118
+ Product.last.description.should == 'dd'
119
+ end
120
+
121
+ it "works through update_attributes" do
122
+ p = Product.create!(:title=>'xx', :description=>'dd')
123
+ p.update_attributes(:title=>'yy')
124
+ Product.last.title.should == 'yy'
125
+ Product.last.description.should == 'dd'
126
+ end
127
+
128
+ it "works through attributes=" do
129
+ p = Product.create!(:title=>'xx', :description=>'dd')
130
+ p.attributes = {:title=>'yy'}
131
+ p.save!
132
+ Product.last.title.should == 'yy'
133
+ Product.last.description.should == 'dd'
134
+ end
135
+
136
+ it "loads translations once" do
137
+ Product.create!(:title=>'xx', :description=>'yy')
138
+ p = Product.last
139
+ p.translations.should_receive(:all).and_return []
140
+ p.title.should == nil
141
+ p.description.should == nil
142
+ end
143
+
144
+ it "deletes the existing translation when changing to blank" do
145
+ p = Product.create!(:title=>'1')
146
+ lambda{
147
+ p.title = ''
148
+ p.save!
149
+ }.should change(Translation, :count).by(-1)
150
+ Product.last.title.should == nil
151
+ end
152
+
153
+ it "can store multiple translations at once" do
154
+ lambda{
155
+ Product.create!(:title_in_de=>'Hallo', :title_in_en=>'Hello')
156
+ }.should change(Translation, :count).by(+2)
157
+ Product.last.title_in_de.should == 'Hallo'
158
+ Product.last.title.should == 'Hello'
159
+ end
160
+
161
+ it "deletes translations when translatable is destroyed" do
162
+ Translation.delete_all
163
+ Product.create!(:title=>'t1')
164
+ Product.create!(:title=>'t2',:description=>'d2')
165
+ Translation.count.should == 3
166
+
167
+ Product.last.destroy
168
+
169
+ Translation.count.should == 1
170
+ Translation.first.text.should == 't1'
171
+ end
172
+
173
+ it "is not influenced by reloading" do
174
+ p = Product.create!(:title=>'t1', :description=>'d1')
175
+ p.title = 't2'
176
+ p.reload
177
+ p.description = 'd2'
178
+ p.save!
179
+ Product.last.title.should == 't2'
180
+ Product.last.description.should == 'd2'
181
+ end
182
+ end
183
+
184
+ describe 'classes' do
185
+ it "does not define them twice" do
186
+ Translation.instance_variable_set '@test', 1
187
+ class XXX < ActiveRecord::Base
188
+ set_table_name :products
189
+ translated_attributes :name
190
+ end
191
+ Translation.instance_variable_get('@test').should == 1
192
+ end
193
+
194
+ it "stores options seperately" do
195
+ Shop.translated_attributes_options[:fields].should_not == Product.translated_attributes_options[:fields]
196
+ end
197
+ end
198
+
199
+ describe 'different tables' do
200
+ it "creates the model for each table_name" do
201
+ Translation
202
+ UserTranslation
203
+ end
204
+
205
+ it "creates translations in set table" do
206
+ Product.create!(:title=>'yyy')
207
+ Translation.last.text.should == 'yyy'
208
+
209
+ User.create!(:name=>'xxx')
210
+ UserTranslation.last.text.should == 'xxx'
211
+ end
212
+ end
213
+
214
+ describe 'nil to blank' do
215
+ it "converts all unfound fields to blank" do
216
+ User.new.name.should == ''
217
+ end
218
+ end
219
+
220
+ describe :translated_attributes do
221
+ it "is a empty hash when nothing was set" do
222
+ Product.new.translated_attributes.should == {}
223
+ end
224
+
225
+ it "can be modified" do
226
+ Product.new.translated_attributes.should_not be_frozen
227
+ end
228
+ end
229
+
230
+ describe :translated_attriutes= do
231
+ it "stores all translations" do
232
+ p = Product.create!
233
+ p.translated_attributes = {:de=>{:title=>'de title',:description=>'de descr'}}
234
+ p.title_in_de.should == 'de title'
235
+ p.description_in_de.should == 'de descr'
236
+ p.title_in_en.should == nil
237
+ end
238
+
239
+ it "overwrites existing translations" do
240
+ p = Product.create!(:title=>'en title')
241
+ p.translated_attributes = {:de=>{:title=>'de title',:description=>'de descr'}}
242
+ p.title_in_de.should == 'de title'
243
+ p.description_in_de.should == 'de descr'
244
+ p.title_in_en.should == nil
245
+ end
246
+
247
+ it "stores and overwrites on save" do
248
+ p = Product.create!(:title=>'en title')
249
+ p.translated_attributes = {:de=>{:title=>'de title',:description=>'de descr'}}
250
+ p.save!
251
+ Product.last.title.should == 'de title'
252
+ Product.last.title_in_de.should == 'de title'
253
+ end
254
+
255
+ it "does not store unknown attributes" do
256
+ p = Product.new
257
+ p.translated_attributes = {:de=>{:xxx=>'de title',:description=>'de descr'}}
258
+ lambda{
259
+ p.save!
260
+ }.should change(Translation, :count).by(+1)
261
+ end
262
+
263
+ it "does not alter the given hash" do
264
+ p = Product.create!(:title=>'en title')
265
+ hash = {:de=>{:title=>'de title',:description=>'de descr'}}
266
+ p.translated_attributes = hash
267
+ hash['de'].should == nil #not converted to indifferent access
268
+ hash[:de][:title].should == 'de title' #still has all attributes
269
+ end
270
+
271
+ it "stores given hash indifferent" do
272
+ p = Product.new
273
+ p.translated_attributes = {'de'=>{'title'=>'title de'}}
274
+ p.translated_attributes[:de][:title].should == 'title de'
275
+ end
276
+ end
277
+
278
+ describe :method_missing do
279
+ it "ignores calls without _in_" do
280
+ lambda{Product.new.title_xxx}.should raise_error
281
+ end
282
+ it "ignores calls with a non-supported attribute" do
283
+ lambda{Product.new.foo_in_de}.should raise_error
284
+ end
285
+ end
286
+
287
+ describe :respond_to? do
288
+ it "ignores calls without _in_" do
289
+ Product.new.respond_to?(:title_xx_xx).should == false
290
+ end
291
+
292
+ it "ignores calls with a non-supported attribute" do
293
+ Product.new.respond_to?(:foo_in_de).should == false
294
+ end
295
+
296
+ it "responds to translated column" do
297
+ Product.new.respond_to?(:title_in_en).should == true
298
+ end
299
+
300
+ it "responds to normal methods" do
301
+ Product.new.respond_to?(:new_record?).should == true
302
+ end
303
+ end
304
+ end
@@ -0,0 +1,62 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{translated_attributes}
8
+ s.version = "0.5.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Grosser"]
12
+ s.date = %q{2009-10-16}
13
+ s.email = %q{grosser.michael@gmail.com}
14
+ s.extra_rdoc_files = [
15
+ "README.markdown"
16
+ ]
17
+ s.files = [
18
+ "MIGRATION",
19
+ "README.markdown",
20
+ "README.markdown",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "VERSION",
24
+ "init.rb",
25
+ "lib/translated_attributes.rb",
26
+ "lib/translated_attributes.rb",
27
+ "spec/integration_spec.rb",
28
+ "spec/integration_spec.rb",
29
+ "spec/models.rb",
30
+ "spec/models.rb",
31
+ "spec/spec_helper.rb",
32
+ "spec/spec_helper.rb",
33
+ "spec/translated_attributes_spec.rb",
34
+ "spec/translated_attributes_spec.rb",
35
+ "translated_attributes.gemspec"
36
+ ]
37
+ s.homepage = %q{http://github.com/grosser/translated_attributes}
38
+ s.rdoc_options = ["--charset=UTF-8"]
39
+ s.require_paths = ["lib"]
40
+ s.rubyforge_project = %q{translated-attr}
41
+ s.rubygems_version = %q{1.3.5}
42
+ s.summary = %q{ActiveRecord/Rails simple translatable attributes}
43
+ s.test_files = [
44
+ "spec/integration_spec.rb",
45
+ "spec/spec_helper.rb",
46
+ "spec/translated_attributes_spec.rb",
47
+ "spec/models.rb"
48
+ ]
49
+
50
+ if s.respond_to? :specification_version then
51
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
52
+ s.specification_version = 3
53
+
54
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
55
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
56
+ else
57
+ s.add_dependency(%q<activerecord>, [">= 0"])
58
+ end
59
+ else
60
+ s.add_dependency(%q<activerecord>, [">= 0"])
61
+ end
62
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: translated_attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Grosser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-16 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description:
26
+ email: grosser.michael@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.markdown
33
+ files:
34
+ - MIGRATION
35
+ - README.markdown
36
+ - Rakefile
37
+ - VERSION
38
+ - init.rb
39
+ - lib/translated_attributes.rb
40
+ - spec/integration_spec.rb
41
+ - spec/models.rb
42
+ - spec/spec_helper.rb
43
+ - spec/translated_attributes_spec.rb
44
+ - translated_attributes.gemspec
45
+ has_rdoc: true
46
+ homepage: http://github.com/grosser/translated_attributes
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project: translated-attr
69
+ rubygems_version: 1.3.5
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: ActiveRecord/Rails simple translatable attributes
73
+ test_files:
74
+ - spec/integration_spec.rb
75
+ - spec/spec_helper.rb
76
+ - spec/translated_attributes_spec.rb
77
+ - spec/models.rb