multilang-hstore 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,134 @@
1
+ == Multilang-hstore
2
+
3
+ Multilang is a small translation library for translating database values for Rails 3 using the [Hstore datatype](http://www.postgresql.org/docs/9.0/static/hstore.html).
4
+
5
+ This project is a fork of [artworklv/multilang](https://github.com/artworklv/multilang) with some remarkable differences:
6
+
7
+ * Replaced YAML text fields in favor of Hstore fields.
8
+ * The translation hash is no longer limited to locales in `I18n.available_locales`.
9
+
10
+ It uses [engageis/activerecord-postgres-hstore](https://github.com/engageis/activerecord-postgres-hstore)
11
+
12
+ == Installation
13
+
14
+ You need configure the multilang gem inside your gemfile:
15
+
16
+ gem 'multilang-hstore'
17
+
18
+ Do not forget to run
19
+
20
+ bundle install
21
+
22
+
23
+ == Basic Usage
24
+
25
+ This is a walkthrough with all steps you need to setup multilang translated attributes, including model and migration.
26
+
27
+ We're assuming here you want a Post model with some multilang attributes, as outlined below:
28
+
29
+ class Post < ActiveRecord::Base
30
+ multilang :title, :accessible => true
31
+ end
32
+
33
+ or
34
+
35
+ class Post < ActiveRecord::Base
36
+ multilang :title, :description, :required => true, :length => 100, :accessible => true
37
+ end
38
+
39
+ The multilang translations are stored in the same model attributes (eg. title):
40
+
41
+ You may need to create migration for Post as usual, but multilang attributes should be in hstore type:
42
+
43
+ create_table(:posts) do |t|
44
+ t.hstore :title
45
+ t.timestamps
46
+ end
47
+
48
+ Thats it!
49
+
50
+ Now you are able to translate values for the attributes :title and :description per locale:
51
+
52
+ I18n.locale = :en
53
+ post.title = 'Multilang rocks!'
54
+ I18n.locale = :lv
55
+ post.title = 'Multilang rulle!'
56
+
57
+ I18n.locale = :en
58
+ post.title #=> Multilang rocks!
59
+ I18n.locale = :lv
60
+ post.title #=> Multilang rulle!
61
+
62
+
63
+ You may assign attributes through auto generated methods (this methods depend from I18n.available_locales):
64
+
65
+ I18n.available_locales #=> [:en. :lv]
66
+
67
+ post.title_en = 'Multilang rocks!'
68
+ post.title_lv = 'Multilang rulle!'
69
+
70
+ post.title_en #=> 'Multilang rocks!'
71
+ post.title_lv #=> 'Multilang rulle!'
72
+
73
+ You may use mass assignment on model creation (if :accessible param is defined):
74
+
75
+ Post.new(:title => {:en => 'Multilang rocks!', :lv => 'Multilang rulle!'})
76
+
77
+ or
78
+
79
+ Post.new(:title_en => 'Multilang rocks!', :title_lv => 'Multilang rulle!')
80
+
81
+ Also, you may ise same hashes with setters:
82
+
83
+ post.title = {:en => 'Multilang rocks!', :lv => 'Multilang rulle!'}
84
+
85
+ == Attribute methods
86
+
87
+ You may get other translations via attribute translation method:
88
+
89
+ post.title.translation[:lv] #=> 'Multilang rocks!'
90
+ post.title.translation[:en] #=> 'Multilang rulle!'
91
+ post.title.translation.locales #=> [:en, :lv]
92
+
93
+ If you have incomplete translations, you can get translation from other locale:
94
+
95
+ post.title = {:en => 'Multilang rocks!', :lv => ''}
96
+ I18n.locale = :lv
97
+ post.title.any #=> 'Multilang rocks!'
98
+
99
+ The value from "any" method returns value for I18n.current_locale or, if value is empty, it searches through all locales. It takes searching order from I18n.available_locales array.
100
+
101
+ == Validations
102
+ Multilang has some validation features:
103
+
104
+ multilang :title, :length => 100 #define maximal length validator
105
+ multilang :title, :required => true #define requirement validator
106
+ multilang :title, :format => /regexp/ #define validates_format_of validator
107
+
108
+ == Tests
109
+
110
+ Test runs using a temporary database in your local PostgreSQL server:
111
+
112
+ Create a test database:
113
+
114
+ $ createdb multilang-hstore-test
115
+
116
+ Create the [hstore extension](http://www.postgresql.org/docs/9.1/static/sql-createextension.html):
117
+ psql -d multilang-hstore-test -c "CREATE EXTENSION IF NOT EXISTS hstore"
118
+
119
+ Create the role *postgres* if necessary:
120
+
121
+ $ createuser -s -r postgres
122
+
123
+ Finally, you can run your tests:
124
+
125
+ rspec
126
+
127
+ == Bugs and Feedback
128
+
129
+ Use [http://github.com/artworklv/multilang/issues](http://github.com/artworklv/multilang/issues)
130
+
131
+ == License(MIT)
132
+
133
+ Copyright (c) 2010 Arthur Meinart
134
+ Copyright (c) 2012 Firebase.co
@@ -0,0 +1,114 @@
1
+ module Multilang
2
+ module ActiveRecordExtensions
3
+
4
+ module ClassMethods
5
+
6
+ def multilang_accessible_translations
7
+ class_variable_get(:@@multilang_accessible_translations)
8
+ end
9
+
10
+ def multilang(*args)
11
+
12
+ options = {
13
+ :required => false,
14
+ :length => nil,
15
+ :accessible => false,
16
+ :format => nil
17
+ }.merge(args.extract_options!)
18
+
19
+ options.assert_valid_keys([:required, :length, :accessible, :format, :nil])
20
+
21
+ define_translation_base! unless included_modules.include?(InstanceMethods)
22
+
23
+ args.each do |attribute|
24
+
25
+ define_method attribute do
26
+ multilang_translation_keeper(attribute).value
27
+ end
28
+
29
+ define_method "#{attribute}=" do |value|
30
+ multilang_translation_keeper(attribute).update(value)
31
+ end
32
+
33
+ #attribute accessibility for mass assignment
34
+ if options[:accessible]
35
+ matr = multilang_accessible_translations + [attribute.to_sym]
36
+ class_variable_set(:@@multilang_accessible_translations, matr)
37
+ end
38
+
39
+ module_eval do
40
+ serialize "#{attribute}", ActiveRecord::Coders::Hstore
41
+ end
42
+
43
+ I18n.available_locales.each do |locale|
44
+
45
+ define_method "#{attribute}_#{locale}" do
46
+ multilang_translation_keeper(attribute)[locale]
47
+ end
48
+
49
+ define_method "#{attribute}_#{locale}=" do |value|
50
+ multilang_translation_keeper(attribute)[locale] = value
51
+ end
52
+
53
+ # locale based attribute accessibility for mass assignment
54
+ if options[:accessible]
55
+ matr = multilang_accessible_translations + ["#{attribute}_#{locale}".to_sym]
56
+ class_variable_set(:@@multilang_accessible_translations, matr)
57
+ end
58
+
59
+ # attribute presence validator
60
+ if options[:required]
61
+ module_eval do
62
+ validates_presence_of "#{attribute}_#{locale}"
63
+ end
64
+ end
65
+
66
+ #attribute maximal length validator
67
+ if options[:length]
68
+ module_eval do
69
+ validates_length_of "#{attribute}_#{locale}", :maximum => options[:length]
70
+ end
71
+ end
72
+
73
+ #attribute format validator
74
+ if options[:format]
75
+ module_eval do
76
+ validates_format_of "#{attribute}_#{locale}", :with => options[:format]
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+ def define_translation_base!
87
+ include InstanceMethods
88
+
89
+ define_method "multilang_translation_keeper" do |attribute|
90
+ unless instance_variable_defined?("@multilang_attribute_#{attribute}")
91
+ instance_variable_set("@multilang_attribute_#{attribute}", MultilangTranslationKeeper.new(self, attribute))
92
+ end
93
+ instance_variable_get "@multilang_attribute_#{attribute}"
94
+ end
95
+
96
+ unless class_variable_defined?(:@@multilang_accessible_translations)
97
+ class_variable_set(:@@multilang_accessible_translations, [])
98
+ end
99
+
100
+ end
101
+
102
+ end
103
+
104
+ module InstanceMethods
105
+ def mass_assignment_authorizer(role = :default)
106
+ super(role) + (self.class.multilang_accessible_translations || [])
107
+ end
108
+ end #module InstanceMethods
109
+
110
+ end #module ActiveRecordExtensions
111
+ end ##module Multilang
112
+
113
+ ActiveRecord::Base.extend Multilang::ActiveRecordExtensions::ClassMethods
114
+
@@ -0,0 +1,103 @@
1
+ module Multilang
2
+
3
+ class MultilangTranslationKeeper
4
+ attr_reader :model
5
+ attr_reader :attribute
6
+ attr_reader :translations
7
+
8
+ def initialize(model, attribute)
9
+ @model = model
10
+ @attribute = attribute
11
+ @translations = {}
12
+ load!
13
+ end
14
+
15
+ def value(locale = nil)
16
+ locale ||= actual_locale
17
+ read(locale)
18
+ end
19
+
20
+ def current_or_any_value
21
+ v = value
22
+ if v.empty?
23
+ reduced_locales = locales - [actual_locale]
24
+ reduced_locales.each do |locale|
25
+ v = value(locale)
26
+ return v unless v.empty?
27
+ end
28
+ else
29
+ return v
30
+ end
31
+ return ''
32
+ end
33
+
34
+ def to_s
35
+ raw_read(actual_locale)
36
+ end
37
+
38
+ def to_str(locale = nil)
39
+ locale ||= actual_locale
40
+ raw_read(locale)
41
+ end
42
+
43
+ def update(value)
44
+ if value.is_a?(Hash)
45
+ clear
46
+ value.each{|k, v| write(k, v)}
47
+ elsif value.is_a?(String)
48
+ write(actual_locale, value)
49
+ end
50
+ flush!
51
+ end
52
+
53
+ def [](locale)
54
+ read(locale)
55
+ end
56
+
57
+ def []=(locale, value)
58
+ write(locale, value)
59
+ flush!
60
+ end
61
+
62
+ def locales
63
+ @translations.keys.map(&:to_sym)
64
+ end
65
+
66
+ def empty?
67
+ @translations.empty?
68
+ end
69
+
70
+ private
71
+
72
+ def actual_locale
73
+ I18n.locale
74
+ end
75
+
76
+ def write(locale, value)
77
+ @translations[locale.to_s] = value
78
+ end
79
+
80
+ def read(locale)
81
+ MultilangTranslationProxy.new(self, locale)
82
+ end
83
+
84
+ def raw_read(locale)
85
+ @translations[locale.to_s] || ''
86
+ end
87
+
88
+ def clear
89
+ @translations.clear
90
+ end
91
+
92
+ def load!
93
+ data = @model[@attribute]
94
+ data = data.blank? ? nil : data
95
+ @translations = data.is_a?(Hash) ? data : {}
96
+ end
97
+
98
+ def flush!
99
+ @model[@attribute] = @translations
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,22 @@
1
+ module Multilang
2
+ class MultilangTranslationProxy < String
3
+ attr_reader :multilang_keeper
4
+
5
+ def initialize(multi_keeper, locale)
6
+ @multilang_keeper = multi_keeper
7
+ super(@multilang_keeper.to_str(locale))
8
+ end
9
+
10
+ def translation
11
+ @multilang_keeper
12
+ end
13
+
14
+ def to_s
15
+ String.new(self)
16
+ end
17
+
18
+ def any
19
+ @multilang_keeper.current_or_any_value
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Multilang
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'multilang-hstore/version'
2
+ require 'multilang-hstore/translation_proxy'
3
+ require 'multilang-hstore/translation_keeper'
4
+ require 'multilang-hstore/active_record_extensions'
5
+
6
+ module Multilang
7
+ end
@@ -0,0 +1,258 @@
1
+ # -*- coding: utf-8 -*-
2
+ $KCODE = "U"
3
+
4
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
5
+
6
+ describe Multilang do
7
+ before :each do
8
+ setup_db
9
+ I18n.locale = :lv
10
+ end
11
+
12
+ after :each do
13
+ teardown_db
14
+ end
15
+
16
+ it "should test database connection" do
17
+ AbstractPost.create
18
+ AbstractPost.count.should == 1
19
+ end
20
+
21
+ it "should add getters/setters in RegularPost" do
22
+ regular_post = RegularPost.new
23
+ %w(title body).each do |attr|
24
+ regular_post.should respond_to(attr)
25
+ regular_post.should respond_to("#{attr}=")
26
+ I18n.available_locales.each do |loc|
27
+ regular_post.should respond_to("#{attr}_#{loc}")
28
+ regular_post.should respond_to("#{attr}_#{loc}=")
29
+ end
30
+ end
31
+ end
32
+
33
+ it "should set attributes in RegularPost" do
34
+ rp = RegularPost.new
35
+
36
+ # set
37
+ rp.title = "Latviešu nosaukums"
38
+ rp.body = "Latviešu apraksts"
39
+ I18n.locale = :ru
40
+ rp.title = "Русский заголовок"
41
+ rp.body = "Русский текст"
42
+
43
+ # test
44
+ I18n.locale = :lv
45
+ rp.title.should == "Latviešu nosaukums"
46
+ rp.body.should == "Latviešu apraksts"
47
+
48
+ I18n.locale = :ru
49
+ rp.title.should == "Русский заголовок"
50
+ rp.body.should == "Русский текст"
51
+ end
52
+
53
+ it "should set attributes through alternative setters in RegularPost" do
54
+ rp = RegularPost.new
55
+
56
+ # set
57
+ rp.title_lv = "Latviešu nosaukums"
58
+ rp.body_lv = "Latviešu apraksts"
59
+ rp.title_ru = "Русский заголовок"
60
+ rp.body_ru = "Русский текст"
61
+
62
+ # test
63
+ rp.title_lv.should == "Latviešu nosaukums"
64
+ rp.body_lv.should == "Latviešu apraksts"
65
+ rp.title_ru.should == "Русский заголовок"
66
+ rp.body_ru.should == "Русский текст"
67
+
68
+ I18n.locale = :lv
69
+ rp.title.should == "Latviešu nosaukums"
70
+ rp.body.should == "Latviešu apraksts"
71
+
72
+ I18n.locale = :ru
73
+ rp.title.should == "Русский заголовок"
74
+ rp.body.should == "Русский текст"
75
+ end
76
+
77
+ it "should set attributes through fullset hash in RegularPost" do
78
+ rp = RegularPost.new
79
+
80
+ # set
81
+ rp.title = {:lv => "Latviešu nosaukums", :ru => "Русский заголовок"}
82
+ rp.body = {:lv => "Latviešu apraksts", :ru => "Русский текст"}
83
+
84
+ # test
85
+ rp.title_lv.should == "Latviešu nosaukums"
86
+ rp.body_lv.should == "Latviešu apraksts"
87
+ rp.title_ru.should == "Русский заголовок"
88
+ rp.body_ru.should == "Русский текст"
89
+ end
90
+
91
+ it "should set attributes through halfset hash in RegularPost" do
92
+ rp = RegularPost.new
93
+
94
+ # set
95
+ rp.title = {:lv => "Latviešu nosaukums"}
96
+ rp.body = {:lv => "Latviešu apraksts"}
97
+
98
+ # test
99
+ rp.title_lv.should == "Latviešu nosaukums"
100
+ rp.body_lv.should == "Latviešu apraksts"
101
+ rp.title_ru.should == ""
102
+ rp.body_ru.should == ""
103
+ end
104
+
105
+ it "should be validated in RegularPost" do
106
+ rp = RegularPost.new
107
+
108
+ rp.title = "Latviešu nosaukums"
109
+ rp.body = "Latviešu apraksts"
110
+ I18n.locale = :ru
111
+ rp.title = "Русский заголовок"
112
+ rp.body = "Русский текст"
113
+
114
+ rp.should be_valid
115
+ end
116
+
117
+ it "should not be validated in RegularPost" do
118
+ rp = RegularPost.new
119
+
120
+ rp.title_lv = "Latviešu nosaukums"*100 #too long
121
+ rp.body_lv = "" #empty
122
+ rp.title_ru = "" #empty
123
+ rp.body_ru = "Русский текст"*1000 #too long
124
+
125
+ rp.valid?
126
+
127
+ rp.should have(4).errors
128
+ end
129
+
130
+ it "should mass assign attributes in RegularPost" do
131
+ rp = RegularPost.new( :title_lv => "Latviešu nosaukums",
132
+ :title_ru => "Русский заголовок",
133
+ :body_lv => "Latviešu apraksts",
134
+ :body_ru => "Русский текст" )
135
+
136
+ # test
137
+ rp.title_lv.should == "Latviešu nosaukums"
138
+ rp.body_lv.should == "Latviešu apraksts"
139
+ rp.title_ru.should == "Русский заголовок"
140
+ rp.body_ru.should == "Русский текст"
141
+ end
142
+
143
+ it "should not mass assign attributes in ProtectedPost" do
144
+ rp = ProtectedPost.new( :title_lv => "Latviešu nosaukums",
145
+ :title_ru => "Русский заголовок",
146
+ :body_lv => "Latviešu apraksts",
147
+ :body_ru => "Русский текст" )
148
+
149
+ # test
150
+ rp.title_lv.should_not == "Latviešu nosaukums"
151
+ rp.body_lv.should_not == "Latviešu apraksts"
152
+ rp.title_ru.should_not == "Русский заголовок"
153
+ rp.body_ru.should_not == "Русский текст"
154
+ end
155
+
156
+
157
+ it "should mass assign attributes in RegulularPost, v2" do
158
+ rp = RegularPost.new( { :title => {
159
+ :lv => "Latviešu nosaukums",
160
+ :ru => "Русский заголовок"
161
+ },
162
+ :body => {:lv => "Latviešu apraksts",
163
+ :ru => "Русский текст"
164
+ }
165
+ } )
166
+
167
+ # test
168
+ rp.title_lv.should == "Latviešu nosaukums"
169
+ rp.body_lv.should == "Latviešu apraksts"
170
+ rp.title_ru.should == "Русский заголовок"
171
+ rp.body_ru.should == "Русский текст"
172
+ end
173
+
174
+ it "should not not mass assign attributes in ProtectedPost, v2" do
175
+ rp = ProtectedPost.new( { :title => {
176
+ :lv => "Latviešu nosaukums",
177
+ :ru => "Русский заголовок"
178
+ },
179
+ :body => {:lv => "Latviešu apraksts",
180
+ :ru => "Русский текст"
181
+ }
182
+ } )
183
+
184
+ # test
185
+ rp.title_lv.should_not == "Latviešu nosaukums"
186
+ rp.body_lv.should_not == "Latviešu apraksts"
187
+ rp.title_ru.should_not == "Русский заголовок"
188
+ rp.body_ru.should_not == "Русский текст"
189
+ end
190
+
191
+ it "should save/load attributes in RegularPost" do
192
+ rp = RegularPost.new( :title_lv => "Latviešu nosaukums",
193
+ :title_ru => "Русский заголовок",
194
+ :body_lv => "Latviešu apraksts",
195
+ :body_ru => "Русский текст" )
196
+
197
+ rp.save
198
+
199
+ rp = RegularPost.last
200
+
201
+ rp.title_lv.should == "Latviešu nosaukums"
202
+ rp.body_lv.should == "Latviešu apraksts"
203
+ rp.title_ru.should == "Русский заголовок"
204
+ rp.body_ru.should == "Русский текст"
205
+ end
206
+
207
+ it "should save attributes in db as indexable values" do
208
+ rp = RegularPost.new( :title_lv => "Latviešu nosaukums",
209
+ :title_ru => "Русский заголовок",
210
+ :body_lv => "Latviešu apraksts",
211
+ :body_ru => "Русский текст" )
212
+
213
+ rp.save
214
+
215
+ rp = RegularPost.last
216
+
217
+ rp.title_before_type_cast.should == {"lv"=>"Latviešu nosaukums", "ru"=>"Русский заголовок"}
218
+ rp.body_before_type_cast.should == {"lv"=>"Latviešu apraksts", "ru"=>"Русский текст"}
219
+ end
220
+
221
+ it "should return proxied attribute" do
222
+ rp = RegularPost.new( :title_lv => "Latviešu nosaukums",
223
+ :title_ru => "Русский заголовок",
224
+ :body_lv => "Latviešu apraksts",
225
+ :body_ru => "Русский текст" )
226
+
227
+
228
+ rp.title.should be_an_instance_of(Multilang::MultilangTranslationProxy)
229
+ rp.title.should be_a_kind_of(String)
230
+
231
+ rp.body.should respond_to(:translation)
232
+ rp.title.translation[:lv].should == "Latviešu nosaukums"
233
+ rp.body.translation[:ru].should == "Русский текст"
234
+
235
+ rp.title.to_s.should be_an_instance_of(String)
236
+ end
237
+
238
+ it "should set/get some attributes in/from PartialrPost" do
239
+ rp = RegularPost.new
240
+
241
+ # set
242
+ rp.title = "Latviešu nosaukums"
243
+ rp.body = "Latviešu apraksts"
244
+
245
+ # test
246
+ I18n.locale = :lv
247
+ rp.title.should == "Latviešu nosaukums"
248
+ rp.body.should == "Latviešu apraksts"
249
+
250
+ I18n.locale = :ru
251
+ rp.title.should == ""
252
+ rp.body.should == ""
253
+
254
+ rp.title.any.should == "Latviešu nosaukums"
255
+ rp.body.any.should == "Latviešu apraksts"
256
+
257
+ end
258
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,19 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+ create_table :abstract_posts do |t|
3
+ t.hstore :title
4
+ t.hstore :body
5
+ t.integer :void, :default => 1
6
+ end
7
+
8
+ #create_table :posts do |t|
9
+ # t.text :title
10
+ # t.text :body
11
+ # t.integer :void, :default => 1
12
+ #end
13
+
14
+ #create_table :pages do |t|
15
+ # t.text :title
16
+ # t.text :body
17
+ # t.integer :void, :default => 1
18
+ #end
19
+ end
@@ -0,0 +1,63 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
2
+ $:.unshift File.expand_path(File.dirname(__FILE__))
3
+
4
+ require 'rubygems'
5
+ require 'active_support'
6
+ require 'active_record'
7
+ require 'activerecord-postgres-hstore/activerecord'
8
+ require 'activerecord-postgres-hstore/coder'
9
+ require 'activerecord-postgres-hstore/hash'
10
+ require 'activerecord-postgres-hstore/string'
11
+ require 'multilang-hstore'
12
+ require 'logger'
13
+
14
+ ActiveRecord::Base.logger = Logger.new(nil)
15
+ ActiveRecord::Base.establish_connection(:adapter => "postgresql", :database => "multilang-hstore-test", :host=>'127.0.0.1', :user=>'postgres')
16
+
17
+ I18n.available_locales = [:lv, :ru]
18
+ I18n.locale = I18n.default_locale = :lv
19
+
20
+ def setup_db
21
+ ActiveRecord::Migration.verbose = false
22
+ load "schema.rb"
23
+ end
24
+
25
+ def teardown_db
26
+ ActiveRecord::Base.connection.tables.each do |table|
27
+ ActiveRecord::Base.connection.drop_table(table)
28
+ end
29
+ end
30
+
31
+ #testable models
32
+ class AbstractPost < ActiveRecord::Base
33
+ serialize :title, ActiveRecord::Coders::Hstore
34
+ serialize :body, ActiveRecord::Coders::Hstore
35
+ end
36
+
37
+ class MinimalPost < ActiveRecord::Base
38
+ self.table_name = 'abstract_posts'
39
+ multilang :title, :required => false, :accessible => true
40
+ multilang :body, :required => false, :accessible => true
41
+ attr_accessible :void
42
+ end
43
+
44
+ class RegularPost < ActiveRecord::Base
45
+ self.table_name = 'abstract_posts'
46
+ multilang :title, :required => true, :length => 25, :accessible => true
47
+ multilang :body, :required => true, :length => 1000, :accessible => true
48
+ attr_accessible :void
49
+ end
50
+
51
+ class ProtectedPost < ActiveRecord::Base
52
+ self.table_name = 'abstract_posts'
53
+ multilang :title, :accessible => false
54
+ multilang :body, :accessible => false
55
+ attr_accessible :void
56
+ end
57
+
58
+ class PartialPost < ActiveRecord::Base
59
+ self.table_name = 'abstract_posts'
60
+ multilang :title
61
+ multilang :body
62
+ attr_accessible :void
63
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: multilang-hstore
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Arthur Meinart
9
+ - Firebase.co
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-10-29 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: Model translations for Rails 3 backed by PostgreSQL and Hstore
16
+ email: hello@firebase.co
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files:
20
+ - README.rdoc
21
+ files:
22
+ - lib/multilang-hstore.rb
23
+ - lib/multilang-hstore/active_record_extensions.rb
24
+ - lib/multilang-hstore/translation_keeper.rb
25
+ - lib/multilang-hstore/translation_proxy.rb
26
+ - lib/multilang-hstore/version.rb
27
+ - README.rdoc
28
+ - spec/multilang_spec.rb
29
+ - spec/schema.rb
30
+ - spec/spec_helper.rb
31
+ homepage: http://github.com/firebaseco/multilang-hstore
32
+ licenses: []
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 1.8.24
52
+ signing_key:
53
+ specification_version: 3
54
+ summary: Model translations for Rails 3 backed by PostgreSQL and Hstore
55
+ test_files:
56
+ - spec/multilang_spec.rb
57
+ - spec/schema.rb
58
+ - spec/spec_helper.rb
59
+ has_rdoc: