clicrdv_easy_translatable 0.4.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 50704672bccd72c0179e2acd83114e675d7c2301c564ba81a011fa64ac6c3f8c
4
+ data.tar.gz: cf389801803b8822a553c465e9e0568dbbfb2b5a320626a600ced51181b94588
5
+ SHA512:
6
+ metadata.gz: 84a2c46f6ad7282664eaf750596f14a348e0a1a289fdac4dd0edb8deeed6af1d4b500a8b469f0614dd44492f4581818c01be9d96d12c1ab739414917078efed6
7
+ data.tar.gz: 7da00eed5cb246f1ace53df770e3887412c84854899a2189467d1c052467681239e883e7481227b07c4bebef643fbdce7776572853e12fa0cf35efc39f73c5a7
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2008, 2009, 2010 Sven Fuchs, Joshua Harvey, Clemens Kofler, John-Paul Bader, ClicRDV
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Translatable [![Gem Version](https://badge.fury.io/rb/easy_translatable.png)](http://badge.fury.io/rb/easy_translatable) [![Code Climate](https://codeclimate.com/github/clicrdv/translatable.png)](https://codeclimate.com/github/clicrdv/translatable) [![Build Status](https://travis-ci.org/clicrdv/translatable.png)](https://travis-ci.org/clicrdv/translatable) [![Coverage Status](https://coveralls.io/repos/clicrdv/translatable/badge.png)](https://coveralls.io/r/clicrdv/translatable)
2
+ ## Requirements
3
+
4
+ * ActiveRecord 3.2
5
+ * I18n
6
+
7
+ ## Installation
8
+
9
+ To install just use:
10
+
11
+ ```ruby
12
+ gem install easy_translatable
13
+ ```
14
+
15
+ When using bundler put this in your Gemfile:
16
+
17
+ ```ruby
18
+ gem 'easy_translatable', '~> 0.1.0'
19
+ ```
20
+
21
+ ## Todo
22
+
23
+ - cleanup
24
+ - doc
25
+ - migration/model for translation table
26
+
27
+
28
+ Copyright (c) 2008, 2009, 2010 Sven Fuchs, Joshua Harvey, Clemens Kofler, John-Paul Bader, ClicRDV
@@ -0,0 +1,67 @@
1
+ module Translatable
2
+ module ActiveRecord
3
+ class Adapter
4
+ # The cache caches attributes that already were looked up for read access.
5
+ # The stash keeps track of new or changed values that need to be saved.
6
+ attr_accessor :record, :stash, :translations
7
+ private :record=, :stash=
8
+
9
+ def initialize(record)
10
+ self.record = record
11
+ self.stash = Attributes.new
12
+ end
13
+
14
+ def fetch_stash(locale, name)
15
+ value = stash.read(locale, name)
16
+ return value if value
17
+ return nil
18
+ end
19
+
20
+ def stash_contains?(locale, name)
21
+ stash.contains?(locale, name)
22
+ end
23
+
24
+ def fetch(locale, name, value = nil)
25
+ value = stash_contains?(locale, name) ? fetch_stash(locale, name) : fetch_attribute(locale, name, value)
26
+
27
+ return value
28
+ end
29
+
30
+ def write(locale, name, value)
31
+ stash.write(locale, name, value)
32
+ end
33
+
34
+ def save_translations!
35
+ stash.reject {|locale, attrs| attrs.empty?}.each do |locale, attrs|
36
+ translations = record.translations_by_locale[locale]
37
+ attrs.each { |name, value|
38
+ translation = translations && translations[name] ||
39
+ record.translations.build(:locale => locale.to_s, :scope => record.class.table_name, :key => name)
40
+ translation['record_id'] = record.id
41
+ translation['value'] = value
42
+ translation.save!
43
+ }
44
+ end
45
+
46
+ reset
47
+ end
48
+
49
+ def reset
50
+ stash.clear
51
+ end
52
+
53
+ protected
54
+
55
+ def fetch_attribute(locale, name, value = nil)
56
+ if value.nil?
57
+ translation = record.translation_for(locale, name)
58
+ return translation && translation.send(:value)
59
+ else
60
+ translation = record.translation_for_serialized(locale, name, value)
61
+ return translation
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,27 @@
1
+ # Helper class for storing values per locale. Used by Globalize::Adapter
2
+ # to stash and cache attribute values.
3
+
4
+ module Translatable
5
+ module ActiveRecord
6
+ class Attributes < Hash # TODO: Think about using HashWithIndifferentAccess ?
7
+ def [](locale)
8
+ locale = locale.to_sym
9
+ self[locale] = {} unless has_key?(locale)
10
+ self.fetch(locale)
11
+ end
12
+
13
+ def contains?(locale, name)
14
+ self[locale].has_key?(name.to_s)
15
+ end
16
+
17
+ def read(locale, name)
18
+ self[locale][name.to_s]
19
+ end
20
+
21
+ def write(locale, name, value)
22
+ #raise 'z' if value.nil? # TODO
23
+ self[locale][name.to_s] = value
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,60 @@
1
+ module Translatable
2
+ module ActiveRecord
3
+ module ClassMethods
4
+ def translation_class
5
+ Translatable.translation_class
6
+ end
7
+
8
+ def translated?(name)
9
+ included = translated_attribute_names.detect { |attr| attr.is_a?(Hash) ? attr.keys.include?(name.to_sym) : attr == name.to_sym }
10
+ !included.nil?
11
+ end
12
+
13
+ protected
14
+
15
+ def translated_attr_accessor(name)
16
+ define_method(:"#{name}=") do |value|
17
+ write_attribute(name, value)
18
+ end
19
+ define_method(name) do |*args|
20
+ self.read_attribute(name, {:locale => args.detect {|a| !a.is_a? Hash }})
21
+ end
22
+ alias_method :"#{name}_before_type_cast", name
23
+ end
24
+
25
+ def locale_from(args)
26
+ args.detect {|a| !a.is_a? Hash }
27
+ end
28
+
29
+ def translations_accessor(name)
30
+ define_method(:"#{name}_translations") do
31
+ translations.each_with_object(HashWithIndifferentAccess.new) do |translation, result|
32
+ result[translation.locale] = translation.send(name)
33
+ end
34
+ end
35
+ define_method(:"#{name}_translations=") do |value|
36
+ value.each do |(locale, value)|
37
+ write_attribute name, value, :locale => locale
38
+ end
39
+ end
40
+ end
41
+
42
+ def condition_callback(attr_names, callback)
43
+ Proc.new { |rec|
44
+ attr_names.any? do |translatable_attr|
45
+ callback && rec.changes.keys.include?(translatable_attr.to_s)
46
+ end
47
+ }
48
+ end
49
+
50
+ %w(after_save before_save after_update before_update).each do |cb|
51
+ class_eval %{
52
+ def on_#{cb}_callback(attr_names, callback)
53
+ #{cb} callback, :if => condition_callback(attr_names, callback)
54
+ end
55
+ }
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,195 @@
1
+ module Translatable
2
+ module ActiveRecord
3
+ module InstanceMethods
4
+ delegate :translated_locales, :to => :translations
5
+
6
+ def translatable
7
+ @translatable ||= Adapter.new(self)
8
+ end
9
+
10
+ def self.included(base)
11
+ # Maintian Rails 3.0.x compatibility ..
12
+ if base.method_defined?(:assign_attributes)
13
+ base.class_eval %{
14
+ def assign_attributes(attributes, *options)
15
+ with_given_locale(attributes) { super }
16
+ end
17
+ }
18
+ else
19
+ base.class_eval %{
20
+ def attributes=(attributes, *args)
21
+ with_given_locale(attributes) { super }
22
+ end
23
+
24
+ def update_attributes!(attributes, *args)
25
+ with_given_locale(attributes) { super }
26
+ end
27
+
28
+ def update_attributes(attributes, *args)
29
+ with_given_locale(attributes) { super }
30
+ end
31
+ }
32
+ end
33
+ end
34
+
35
+ # Always call the super method, the attribute is translatable and we asked a translated model
36
+ def write_attribute(name, value, options = {}, &block)
37
+ if r_translated?(name) && translate?
38
+ options = {:locale => Translatable.locale}.merge(options)
39
+
40
+ # We don't want to track any changes, but save the new value in a translation hash
41
+
42
+ translatable.write(options[:locale], name, value)
43
+ else
44
+ super(name, value)
45
+ end
46
+ end
47
+
48
+ def translate
49
+ @translate_me = true
50
+ self
51
+ end
52
+
53
+ def end_translate
54
+ @translate_me = nil
55
+ self
56
+ end
57
+
58
+ def reload(options = nil)
59
+ @translate_me = false
60
+ translation_caches.clear
61
+ translated_attribute_names.each { |name| @attributes.reset(name.to_s) }
62
+ translatable.reset
63
+ super(options)
64
+ end
65
+
66
+ def save(*)
67
+ @translate_me = false
68
+ super
69
+ end
70
+
71
+ def translate?
72
+ !@translate_me.nil? && @translate_me
73
+ end
74
+
75
+ def read_attribute(name, options = {}, &block)
76
+ options = {:translated => true, :locale => Translatable.locale}.merge(options)
77
+ if r_translated?(name) and options[:translated]
78
+ serialized_value = super(name) if self.attributes.has_key?(name)
79
+ if translate? && (value = translatable.fetch(options[:locale] || Translatable.locale, name, serialized_value))
80
+ value
81
+ else
82
+ super(name)
83
+ end
84
+ else
85
+ super(name)
86
+ end
87
+ end
88
+
89
+ def r_translated?(name)
90
+ self.class.translated?(name)
91
+ end
92
+
93
+ def translated_attributes
94
+ translated_attribute_names.inject({}) do |attributes, name|
95
+ attributes.merge(name.to_s => translation.send(name))
96
+ end
97
+ end
98
+
99
+ # This method is basically the method built into Rails
100
+ # but we have to pass {:translated => false}
101
+ def untranslated_attributes
102
+ attrs = {}
103
+ attribute_names.each do |name|
104
+ attrs[name] = read_attribute(name, {:translated => false})
105
+ end
106
+ attrs
107
+ end
108
+
109
+ def translation_for(locale, name, build_if_missing = false)
110
+ unless translation_caches["#{locale}_#{name}"]
111
+ # Fetch translations from database as those in the translation collection may be incomplete
112
+ _translation = translations.detect{|t| t.locale.to_s == locale.to_s && t.key.to_s == name.to_s }
113
+ _translation ||= translations.build(:locale => locale) if build_if_missing
114
+ translation_caches["#{locale}_#{name}"] = _translation if _translation
115
+ end
116
+ translation_caches["#{locale}_#{name}"]
117
+ end
118
+
119
+ # Fetch translations per keys in the form
120
+ # model_attr_serialized_attribute
121
+ # E.G.1: ```Model``` has attribute ```config``` which has a key ```auto_save```
122
+ # will have a translation key ```config_auto_save```
123
+ # E.G.2: ```Model``` has attribute ```config``` which is an array of ```user_id => ([0-9]+)```
124
+ # will have translations key containing the index: ```config_user_id_0```, ```config_user_id_1```...
125
+ def translation_for_serialized(locale, name, value, build_if_missing = false)
126
+
127
+ unless translation_caches["#{locale}_#{name}"]
128
+ engine = self.attributes.has_key?(name) ? nil : JSON
129
+ deserialized_value = engine.nil? ? value : engine.load(value)
130
+
131
+ only = self.translated_serialized_attributes[name.to_sym].map(&:to_s)
132
+ if only.empty?
133
+ regex_keys = /\A#{name.to_s}_([a-z_]+[a-z])(?:_([0-9]*))?\Z/
134
+ else
135
+ regex_keys = /\A#{name.to_s}_(#{only.join('|')})(?:_([0-9]*))?\Z/
136
+ end
137
+ # Fetch translations from database as those in the translation collection may be incomplete
138
+ _translations = translations.select{|t| t.locale.to_s == locale.to_s && t.key.to_s =~ regex_keys }
139
+ _translations.each do |t|
140
+ matched = t.key.match regex_keys
141
+ unless matched.nil?
142
+ if matched.size == 3
143
+ sub_attr = matched[1]
144
+ index = matched[2].to_i
145
+ value[index][sub_attr] = t.value if value.size > index && value[index].has_key?(sub_attr)
146
+ elsif matched.size == 3
147
+ sub_attr = matched[1]
148
+ value[sub_attr] = t.value if value.has_key?(sub_attr)
149
+ end
150
+ end
151
+ end
152
+
153
+ translation_caches["#{locale}_#{name}"] = value
154
+ end
155
+ translation_caches["#{locale}_#{name}"]
156
+ end
157
+
158
+ def translation_caches
159
+ @translation_caches ||= {}
160
+ end
161
+
162
+
163
+ def with_given_locale(attributes, &block)
164
+ attributes.symbolize_keys! if attributes.respond_to?(:symbolize_keys!)
165
+
166
+ locale = respond_to?(:locale=) ? attributes.try(:[], :locale) :
167
+ attributes.try(:delete, :locale)
168
+
169
+ if locale && !respond_to?(:locale=)
170
+ already = translate?
171
+ translate unless translate?
172
+ Translatable.with_locale(locale, &block)
173
+ end_translate unless already
174
+ else
175
+ yield
176
+ end
177
+ end
178
+
179
+ def translations_by_locale(&block)
180
+ translations.each_with_object(HashWithIndifferentAccess.new) do |t, hash|
181
+ hash[t.locale] ||= HashWithIndifferentAccess.new
182
+ hash[t.locale][t.key] = block_given? ? block.call(t) : t
183
+ end
184
+ end
185
+
186
+ protected
187
+
188
+ def save_translations!
189
+ translatable.save_translations!
190
+ translation_caches.clear
191
+ end
192
+
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,96 @@
1
+ module Translatable
2
+ module ActiveRecord
3
+ module Macro
4
+
5
+ def translatable(*attr_names)
6
+
7
+ options = attr_names.extract_options!
8
+ setup_translatable!(options) unless translatable?
9
+
10
+ attr_names = attr_names.map(&:to_sym)
11
+ attr_names -= translated_attribute_names if defined?(translated_attribute_names)
12
+
13
+ if attr_names.present?
14
+
15
+ attr_names.each do |attr_name|
16
+ # Create accessors for the attribute.
17
+ translated_attr_accessor(attr_name)
18
+ translations_accessor(attr_name)
19
+
20
+ # Add attribute to the list.
21
+ self.translated_attribute_names << attr_name
22
+ if options[:only]
23
+ self.translated_serialized_attributes[attr_name] = options[:only] ? options[:only] : []
24
+ end
25
+ end
26
+
27
+ on_after_save_callback(attr_names, options[:after_save]) if options[:after_save]
28
+ on_before_save_callback(attr_names, options[:before_save]) if options[:before_save]
29
+ on_after_update_callback(attr_names, options[:after_update]) if options[:after_update]
30
+ on_before_update_callback(attr_names, options[:before_update]) if options[:before_update]
31
+
32
+ Translatable.add_translatable self
33
+
34
+ end
35
+ end
36
+
37
+ def class_name
38
+ @class_name ||= begin
39
+ class_name = table_name[table_name_prefix.length..-(table_name_suffix.length + 1)].downcase.camelize
40
+ pluralize_table_names ? class_name.singularize : class_name
41
+ end
42
+ end
43
+
44
+ def translatable?
45
+ included_modules.include?(InstanceMethods)
46
+ end
47
+
48
+ protected
49
+ def setup_translatable!(options)
50
+ options[:table_name] ||= Translatable.translation_class.table_name
51
+ options[:foreign_key] ||= 'record_id'
52
+ options[:conditions] ||= {}
53
+ options[:after_save] ||= false
54
+ options[:before_save] ||= false
55
+
56
+ class_attribute :translated_attribute_names, :translation_options, :fallbacks_for_empty_translations, :translated_serialized_attributes
57
+ self.translated_attribute_names = []
58
+ self.translation_options = options
59
+ self.fallbacks_for_empty_translations = options[:fallbacks_for_empty_translations]
60
+ self.translated_serialized_attributes = Hash.new
61
+
62
+ include InstanceMethods
63
+ extend ClassMethods
64
+
65
+ translation_class.table_name = options[:table_name]
66
+
67
+ has_many :translations, conditions(options), :class_name => translation_class.name,
68
+ :foreign_key => options[:foreign_key],
69
+ :dependent => :destroy,
70
+ :extend => HasManyExtensions,
71
+ :autosave => false
72
+
73
+ after_create :save_translations!
74
+ after_update :save_translations!
75
+ end
76
+
77
+ def conditions(options)
78
+ table_name = self.table_name
79
+ proc {
80
+ c = options[:conditions]
81
+ c = self.instance_eval(&c) if c.is_a?(Proc)
82
+ c.merge!(:scope => table_name, :locale => Translatable.locale)
83
+
84
+ where(c)
85
+ }
86
+ end
87
+
88
+ end
89
+
90
+ module HasManyExtensions
91
+ def find_or_initialize_by_locale(locale)
92
+ with_locale(locale.to_s).first || build(:locale => locale.to_s)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,31 @@
1
+ module Translatable
2
+ module ActiveRecord
3
+ module Relation
4
+ def exec_queries
5
+ queries = super
6
+
7
+ return queries.map(&:translate) if @translate_records
8
+
9
+ queries
10
+ end
11
+
12
+ private
13
+
14
+ def translate
15
+ @translate_records = true
16
+
17
+ self.eager_load(:translations)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ class Railtie < Rails::Railtie
24
+
25
+ initializer "easy_translatable.configure_rails_initialization" do
26
+ ActiveSupport.on_load(:active_record) do
27
+ ActiveRecord::Relation.send :prepend, Translatable::ActiveRecord::Relation
28
+ end
29
+ end
30
+
31
+ end if defined?(Rails)
@@ -0,0 +1,10 @@
1
+ module Translatable
2
+ module ActiveRecord
3
+ module Translate
4
+ def self.translate
5
+ self.scoped.translate
6
+ end
7
+
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path '../active_record/class_methods.rb', __FILE__
2
+ require File.expand_path '../active_record/instance_methods.rb', __FILE__
3
+ require File.expand_path '../active_record/attributes.rb', __FILE__
4
+ require File.expand_path '../active_record/adapter.rb', __FILE__
5
+ require File.expand_path '../active_record/macro.rb', __FILE__
6
+ require File.expand_path '../active_record/translate.rb', __FILE__
7
+ require File.expand_path '../active_record/relation.rb', __FILE__
8
+
9
+ module Translatable
10
+ module ActiveRecord
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ require 'active_record'
2
+ require File.expand_path '../active_record.rb', __FILE__
3
+
4
+ ActiveRecord::Base.extend(Translatable::ActiveRecord::Translate)
5
+ ActiveRecord::Base.extend(Translatable::ActiveRecord::Macro)
@@ -0,0 +1,3 @@
1
+ module Translatable
2
+ VERSION = '0.4.0'
3
+ end
@@ -0,0 +1,68 @@
1
+ require File.join(File.dirname(__FILE__), 'translatable/default.rb')
2
+
3
+ module Translatable
4
+
5
+ @@translatable ||= Hash.new
6
+ @@translation_class ||= nil
7
+
8
+ class << self
9
+ def locale
10
+ read_locale || I18n.locale
11
+ end
12
+
13
+ def locale=(locale)
14
+ set_locale(locale)
15
+ end
16
+
17
+ def with_locale(locale, &block)
18
+ previous_locale = read_locale
19
+ begin
20
+ set_locale(locale)
21
+ result = yield(locale)
22
+ ensure
23
+ set_locale(previous_locale)
24
+ end
25
+ result
26
+ end
27
+
28
+ def translation_class_name=(klass)
29
+ @@translation_class = klass.constantize
30
+ end
31
+ def translation_class
32
+ @@translation_class ||= nil
33
+ end
34
+
35
+ # Hash of models that are translatable (values are the attrs)
36
+ def list
37
+ @@translatable ||= Hash.new
38
+ end
39
+
40
+ def add_translatable(klass)
41
+ if @@translatable.has_key? klass.name
42
+ klass.translated_attribute_names.each do |attr|
43
+ @@translatable[klass.name] << attr unless @@translatable[klass.name].include?(attr)
44
+ end
45
+ else
46
+ @@translatable[klass.name] = klass.translated_attribute_names
47
+ end
48
+
49
+ unless klass.translated_serialized_attributes.nil?
50
+ @@translatable[klass.name].map! do |attr|
51
+ serialized = klass.translated_serialized_attributes.reject{|k,v| k != attr}
52
+ serialized.empty? ? attr : serialized
53
+ end
54
+ end
55
+ end
56
+
57
+ protected
58
+
59
+ def read_locale
60
+ Thread.current[:translatable_locale]
61
+ end
62
+
63
+ def set_locale(locale)
64
+ Thread.current[:translatable_locale] = locale.try(:to_sym)
65
+ end
66
+ end
67
+
68
+ end
metadata ADDED
@@ -0,0 +1,203 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clicrdv_easy_translatable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Paul Bonaud
8
+ - Charly Poly
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2022-03-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 6.1.3
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 6.1.3
28
+ - !ruby/object:Gem::Dependency
29
+ name: database_cleaner
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 0.6.0
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: 0.6.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - "~>"
43
+ - !ruby/object:Gem::Version
44
+ version: 0.6.0
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.6.0
48
+ - !ruby/object:Gem::Dependency
49
+ name: mocha
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: pathname_local
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ - !ruby/object:Gem::Dependency
77
+ name: test_declarative
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ - !ruby/object:Gem::Dependency
91
+ name: friendly_id
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ - !ruby/object:Gem::Dependency
105
+ name: sqlite3
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ - !ruby/object:Gem::Dependency
119
+ name: rake
120
+ requirement: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ type: :development
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ - !ruby/object:Gem::Dependency
133
+ name: rdoc
134
+ requirement: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ type: :development
140
+ prerelease: false
141
+ version_requirements: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ - !ruby/object:Gem::Dependency
147
+ name: coveralls
148
+ requirement: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ type: :development
154
+ prerelease: false
155
+ version_requirements: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ description: Handle translations for AR models into a single table. And provide a
161
+ helper to select translated values.
162
+ email: paul.bonaud@clicrdv.com
163
+ executables: []
164
+ extensions: []
165
+ extra_rdoc_files: []
166
+ files:
167
+ - LICENSE
168
+ - README.md
169
+ - lib/translatable.rb
170
+ - lib/translatable/active_record.rb
171
+ - lib/translatable/active_record/adapter.rb
172
+ - lib/translatable/active_record/attributes.rb
173
+ - lib/translatable/active_record/class_methods.rb
174
+ - lib/translatable/active_record/instance_methods.rb
175
+ - lib/translatable/active_record/macro.rb
176
+ - lib/translatable/active_record/relation.rb
177
+ - lib/translatable/active_record/translate.rb
178
+ - lib/translatable/default.rb
179
+ - lib/translatable/version.rb
180
+ homepage: http://rubygems.org/gems/single_translatable
181
+ licenses:
182
+ - MIT
183
+ metadata: {}
184
+ post_install_message:
185
+ rdoc_options: []
186
+ require_paths:
187
+ - lib
188
+ required_ruby_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ requirements: []
199
+ rubygems_version: 3.2.3
200
+ signing_key:
201
+ specification_version: 4
202
+ summary: Handle translations for AR models into a single table
203
+ test_files: []