translateable 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 33573e7e6b019eb8b4dd69ba5ced07f073b22d8b
4
+ data.tar.gz: cd2e4894a80b66e63ca20c6e1b27e7d0358f6084
5
+ SHA512:
6
+ metadata.gz: 59616f8a968c2a9fa1c9dd135a91128c0cd9aacc1189f22a071b1966fa8f686e2c268022ab64d94f6336fedfba6548589207ff30fdc773818ad2e2f46f801e62
7
+ data.tar.gz: 791494b990f7b3549f204763974426ae0f5b88215b41070cb5a624ee87d91a10245d0689b9f923a5d4f839037b83c237e6587d0edc042682c589bea8b9f1e240
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,11 @@
1
+ Style/Documentation:
2
+ Enabled: false
3
+
4
+ Metrics/LineLength:
5
+ Max: 162
6
+
7
+ Style/Lambda:
8
+ Enabled: false
9
+
10
+ Style/FrozenStringLiteralComment:
11
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+
5
+ gemfile:
6
+ - gemfiles/4.2.gemfile
7
+ - gemfiles/5.0.gemfile
8
+
9
+ script:
10
+ - bundle exec rspec
11
+ - bundle exec rubocop
12
+
13
+ before_install: gem install bundler -v 1.11.2
14
+
15
+ services:
16
+ - postgresql
17
+
18
+ addons:
19
+ postgresql: "9.4"
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at oleg.b.antonyan@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in translateable.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Oleg Antonyan
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,234 @@
1
+ # Translateable
2
+
3
+ [![Build Status](https://travis-ci.org/olegantonyan/translateable.svg)](https://travis-ci.org/olegantonyan/translateable)
4
+
5
+ Allows you to store text data in multiple languages with your ActiveRecord models. Similar to [globalize](https://github.com/globalize/globalize), but have a few differences:
6
+
7
+ 1. Works with Rails 5
8
+ 2. Uses single field in the table. No additional tables required to store translated data. PostgreSQL 9.4 is required to do this (JSONB)
9
+ 3. Provides easy integration with forms using nested attributes so you can create records with multiple translations in one form. Together with [nested_form_fields](https://github.com/ncri/nested_form_fields) you can dynamically add/delete/update tranlations without a single line of JavaScript.
10
+
11
+ ```ruby
12
+ I18n.locale = :en
13
+ post = Post.create(title: 'hello')
14
+ post.title #=> hello
15
+
16
+ I18n.locale = :ru
17
+ post.update(title: 'привет')
18
+ post.title #=> привет
19
+
20
+ I18n.locale = :en
21
+ post.title #=> hello
22
+ ```
23
+
24
+ It adds very thin abstraction layer on top of JSONB field. All data is stored in a simple JSON structure: `{ "locale_name": "data" }`. JSONB can be indexed (this is a main reason why use it instead of just JSON, which is available in previous postgres versions).
25
+
26
+ ## Requirements
27
+
28
+ - PostgreSQL >= 9.4
29
+ - ActiveRecord >= 4.2
30
+ - I18n
31
+
32
+ ## Installation
33
+
34
+ Add this line to your application's Gemfile:
35
+
36
+ ```ruby
37
+ gem 'translateable'
38
+ ```
39
+
40
+ And then execute:
41
+
42
+ $ bundle install
43
+
44
+ Or install it yourself as:
45
+
46
+ $ gem install translateable
47
+
48
+ ## Usage
49
+
50
+ Include `Translateable` into your model (or `ApplicationRecord` if you are on Rails 5 and want to include it into all models).
51
+
52
+ Call `translateable` macro with a list of attributes you want to be translateable:
53
+ ```ruby
54
+ class Post < ActiveRecord::Base
55
+ include Translateable
56
+
57
+ translateable :title
58
+ end
59
+ ```
60
+
61
+ Now `title` attribute is translateable:
62
+ ```ruby
63
+ I18n.locale = :en
64
+ post = Post.create(title: 'hello')
65
+ post.title #=> hello
66
+
67
+ I18n.locale = :ru
68
+ post.update(title: 'привет')
69
+ post.title #=> привет
70
+
71
+ I18n.locale = :en
72
+ post.title #=> hello
73
+
74
+ I18n.locale = :it # oops! no translation for 'it' locale, use translation for `I18n.default_locale`
75
+ post.title #=> hello
76
+ ```
77
+
78
+ You can pass multiple attributes:
79
+ ```ruby
80
+ translateable :title, :body
81
+ ```
82
+
83
+ If there is no translation for a selected locale, than `I18n.default_locale` will be used. If there is no translation for `I18n.default_locale`, than first available will be used.
84
+
85
+ You can assign all locales data as a hash at once:
86
+ ```ruby
87
+ post = Post.create(title: { en: 'hello', ru: 'привет' })
88
+ I18n.with_locale(:en) do
89
+ post.title #=> 'hello'
90
+ end
91
+ I18n.with_locale(:ru) do
92
+ post.title #=> 'привет'
93
+ end
94
+ ```
95
+
96
+ You can easily create translated data with form using nested attributes
97
+
98
+ For example, with [simple_form](https://github.com/plataformatec/simple_form) and [nested_form_fields](https://github.com/ncri/nested_form_fields):
99
+ ```haml
100
+ = simple_form_for @post do |f|
101
+ = f.label(:title)
102
+ = f.nested_fields_for Translateable.translateable_attribute_by_name(:title), class_name: 'OpenStruct' do |ff|
103
+ = ff.input :data, label: false
104
+ = ff.input :locale, collection: I18n.available_locales, include_blank: false, label: false
105
+ = ff.remove_nested_fields_link 'Remove translation', role: 'button'
106
+ = f.add_nested_fields_link Translateable.translateable_attribute_by_name(:title), 'Add translation', role: 'button'
107
+ = f.button :submit
108
+ ```
109
+
110
+ Or with built-in `form_for` and [nested_form_fields](https://github.com/ncri/nested_form_fields):
111
+ ```haml
112
+ = form_for @post do |f|
113
+ = f.label :title
114
+ = f.nested_fields_for Translateable.translateable_attribute_by_name(:title), class_name: 'OpenStruct' do |ff|
115
+ = ff.text_field :data
116
+ = ff.select :locale, I18n.available_locales
117
+ = ff.remove_nested_fields_link 'Remove translation', role: 'button'
118
+ = f.add_nested_fields_link Translateable.translateable_attribute_by_name(:title), 'Add translation', role: 'button'
119
+
120
+ = f.submit
121
+ ```
122
+ Don't forget about strong parameters in your controller:
123
+ ```ruby
124
+ def post_params
125
+ attrs = [:title] + Post.translateable_permitted_attributes
126
+ params.require(:post).permit(*attrs)
127
+ end
128
+
129
+ # `translateable_permitted_attributes` method provides strong_params for all translateable attributes
130
+ # for example with `title` attribute those will be: `title_translateable_attributes: [:locale, :data, :_destroy]`
131
+ ```
132
+ Now you can add/delete/update `title` attribute value in different languages via single form.
133
+
134
+ ### Migration
135
+
136
+ Attributes must exist with `JSONB` type in database, so create a migration:
137
+ ```ruby
138
+ class AddTitleToPosts < ActiveRecord::Migration
139
+ def change
140
+ add_column :posts, :title, :jsonb, null: false, default: '{}'
141
+ end
142
+ end
143
+ ```
144
+
145
+ If you already have a data and want to migrate it to new translateable structure, use provided generator:
146
+ ```
147
+ bin/rails generate translateable:migration posts title
148
+ ```
149
+ This will create a reversible migration for data in `title` field of the `posts` table. By default, existent data will be moved into `I18n.default_locale`. If you want to use another locale, provide it as third argument:
150
+ ```
151
+ bin/rails generate translateable:migration posts title ru
152
+ ```
153
+ Now all existent data will be transfered into new structure with 'ru' locale.
154
+
155
+ Example (using 'en' locale):
156
+ ```sql
157
+ # before migration
158
+ SELECT id,title FROM posts;
159
+ id | title
160
+ ----+-----------------
161
+ 1 | "hello"
162
+ 2 | "world"
163
+
164
+ # after migration
165
+ SELECT id,title FROM posts;
166
+ id | title
167
+ ----+-----------------
168
+ 1 | {"en": "hello"}
169
+ 2 | {"en": "world"}
170
+ ```
171
+
172
+ By default, generator will create a migration with 'gin' index on translateable field. If you you need to use custom path index you have to change it manually.
173
+
174
+ ### Queries
175
+
176
+ You'll probably want to create scopes for this kind of queries.
177
+
178
+ ```ruby
179
+ # get posts where `title` with `en` locale is 'hello'
180
+ Post.where("title->>'en' = ?", 'hello')
181
+
182
+ # get posts where `title` is 'hola' with any locale
183
+ Post.where("EXISTS (SELECT 1 FROM jsonb_each_text(posts.title) j WHERE j.value = ?)", 'hola')
184
+
185
+ # get posts where `title` LIKE 'прив' with any locale ignoring case
186
+ where("EXISTS (SELECT 1 FROM jsonb_each_text(posts.title) j WHERE lower(j.value) LIKE ?)", '%прив%')
187
+ ```
188
+
189
+ I use this concern:
190
+ ```ruby
191
+ # app/models/concerns/jsonb_querable
192
+ module JsonbQuerable
193
+ extend ActiveSupport::Concern
194
+
195
+ included do
196
+ # http://stackoverflow.com/questions/36250331/query-postgres-jsonb-by-value-regardless-of-keys/36251296#36251296
197
+ scope :where_jsonb_value, -> (attribute, value) {
198
+ ta = sanitize("#{table_name}.#{attribute}")[1..-2]
199
+ where("EXISTS (SELECT 1 FROM jsonb_each_text(#{ta}) j WHERE j.value = ?)", value)
200
+ }
201
+
202
+ scope :where_jsonb_value_like, -> (attribute, value, case_sens = false) {
203
+ ta = sanitize("#{table_name}.#{attribute}")[1..-2]
204
+ if case_sens
205
+ where("EXISTS (SELECT 1 FROM jsonb_each_text(#{ta}) j WHERE j.value LIKE ?)", "%#{value}%")
206
+ else
207
+ q = "%#{Unicode.downcase(value.to_s)}%" # Unicode came from 'unicode' gem https://github.com/blackwinter/unicode
208
+ where("EXISTS (SELECT 1 FROM jsonb_each_text(#{ta}) j WHERE lower(j.value) LIKE ?)", q)
209
+ end
210
+ }
211
+ end
212
+ end
213
+ ```
214
+
215
+ Refer to [postgres documentation](http://www.postgresql.org/docs/9.4/static/functions-json.html).
216
+
217
+ ## TODO
218
+
219
+ - Add options (fallback locales lookup behavior maybe?)
220
+ - More clever database management for testing (temp schema or so)
221
+
222
+ ## Development
223
+
224
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
225
+
226
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
227
+
228
+ ## Contributing
229
+
230
+ Bug reports and pull requests are welcome on GitHub at https://github.com/olegantonyan/translateable. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
231
+
232
+ ## License
233
+
234
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'translateable'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 4.2.0'
4
+ gem 'activesupport', '~> 4.2.0'
5
+
6
+ gemspec path: '../'
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 5.0.0.beta1'
4
+ gem 'activesupport', '~> 5.0.0.beta1'
5
+
6
+ gemspec path: '../'
@@ -0,0 +1,37 @@
1
+ if defined?(Rails)
2
+ require 'rails/generators'
3
+ require 'rails/generators/active_record'
4
+
5
+ module Translateable
6
+ class MigrationGenerator < ActiveRecord::Generators::Base
7
+ desc 'Create sample migration with translateable field'
8
+ source_root File.expand_path('../templates', __FILE__)
9
+
10
+ argument :field_name, type: :string
11
+ argument :locale, type: :string, default: I18n.default_locale
12
+
13
+ def create_migration_file
14
+ raise ArgumentError, "given locale #{locale} is not available, check I18n.available_locales" unless I18n.available_locales.include?(locale.to_sym)
15
+ migration_template('migration.rb.erb', "db/migrate/migrate_translateable_#{name}_#{field_name}.rb",
16
+ migration_version: migration_version,
17
+ table_name: name,
18
+ field_name: field_name,
19
+ locale: locale)
20
+ end
21
+
22
+ private
23
+
24
+ def rails5?
25
+ Rails.version.start_with?('5')
26
+ end
27
+
28
+ def migration_version
29
+ if rails5?
30
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
31
+ else
32
+ ''
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ class MigrateTranslateable<%= table_name.camelize + field_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ reversible do |dir|
4
+ dir.up do
5
+ add_column :<%= table_name %>, :<%= field_name + '_t' %>, :jsonb, null: false, default: '{}'
6
+ execute <<-SQL
7
+ UPDATE <%= table_name %> AS m1
8
+ SET <%= field_name + '_t' %> = (
9
+ SELECT row_to_json(t) FROM (
10
+ SELECT <%= field_name %> AS <%= locale %> FROM <%= table_name %> AS m2 WHERE m1.id = m2.id
11
+ ) t
12
+ )::jsonb;
13
+ SQL
14
+ remove_column :<%= table_name %>, :<%= field_name %>
15
+ rename_column :<%= table_name %>, :<%= field_name + '_t' %>, :<%= field_name %>
16
+ add_index :<%= table_name %>, :<%= field_name %>, using: :gin
17
+ end
18
+
19
+ dir.down do
20
+ add_column :<%= table_name %>, :<%= field_name + '_t' %>, :string, null: false, default: ''
21
+ execute <<-SQL
22
+ UPDATE <%= table_name %> AS m1
23
+ SET <%= field_name + '_t' %> = (
24
+ SELECT <%= field_name %>->>'<%= locale %>' AS <%= field_name %> FROM <%= table_name %> AS m2 WHERE m1.id = m2.id
25
+ );
26
+ SQL
27
+ remove_column :<%= table_name %>, :<%= field_name %>
28
+ rename_column :<%= table_name %>, :<%= field_name + '_t' %>, :<%= field_name %>
29
+ add_index :<%= table_name %>, :<%= field_name %>
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module Translateable
2
+ VERSION = '0.1.1'.freeze
3
+ end
@@ -0,0 +1,66 @@
1
+ require 'translateable/version'
2
+
3
+ module Translateable
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ def self.translateable_attribute_by_name(attr)
9
+ "#{attr}_translateable"
10
+ end
11
+
12
+ module ClassMethods
13
+ def translateable(*attrs)
14
+ attrs.each do |attr|
15
+ translateable_sanity_check(attr)
16
+ define_translateable_methods(attr)
17
+ end
18
+ define_translateable_strong_params(*attrs)
19
+ end
20
+
21
+ def translateable_sanity_check(attr)
22
+ attr = attr.to_s
23
+ raise ArgumentError, "no such column '#{attr}' in '#{name}' model" unless column_names.include?(attr)
24
+ raise ArgumentError, "'#{attr}' column must be of JSONB type" unless columns_hash[attr].type.to_s.casecmp('jsonb') == 0
25
+ end
26
+
27
+ def define_translateable_strong_params(*attrs)
28
+ define_singleton_method('translateable_permitted_attributes') do
29
+ attrs.each_with_object([]) { |i, obj| obj << { "#{i}_translateable_attributes" => [:locale, :data, :_destroy] } }
30
+ end
31
+ end
32
+
33
+ # rubocop: disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
34
+ def define_translateable_methods(attr)
35
+ define_method("#{attr}_fetch_translateable") do
36
+ value = self[attr]
37
+ return value.with_indifferent_access if !value.nil? && !value.empty?
38
+ (new_record? ? { I18n.locale => '' } : {}).with_indifferent_access
39
+ end
40
+
41
+ define_method(Translateable.translateable_attribute_by_name(attr)) do
42
+ value = send("#{attr}_fetch_translateable")
43
+ value.map { |k, v| OpenStruct.new(locale: k, data: v) }
44
+ end
45
+
46
+ define_method("#{attr}_translateable_attributes=") do |arg|
47
+ self[attr] = arg.each_with_object({}) do |i, obj|
48
+ hash = i.second
49
+ next if hash[:_destroy]
50
+ obj[hash[:locale]] = hash[:data]
51
+ end
52
+ end
53
+
54
+ define_method(attr) do
55
+ value = send("#{attr}_fetch_translateable")
56
+ value[I18n.locale] || value[I18n.default_locale] || value.values.first
57
+ end
58
+
59
+ define_method("#{attr}=") do |arg|
60
+ value = arg.is_a?(Hash) ? arg : (self[attr] || {}).merge(I18n.locale => arg)
61
+ self[attr] = value
62
+ end
63
+ end
64
+ # rubocop: enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
65
+ end
66
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'translateable/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'translateable'
8
+ spec.version = Translateable::VERSION
9
+ spec.authors = ['Oleg Antonyan']
10
+ spec.email = ['oleg.b.antonyan@gmail.com']
11
+
12
+ spec.summary = 'Allows to store text data in different languages.'
13
+ spec.description = "Similar to globalize, but uses PostgreSQL's JSONB to store data in a single field. No additional tables required. Very thin abstraction"
14
+ spec.homepage = 'https://github.com/olegantonyan/translateable_data'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = %w(lib)
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.11'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+ spec.add_development_dependency 'rubocop'
26
+
27
+ spec.add_dependency 'activerecord', '>= 4.2'
28
+ spec.add_dependency 'activesupport', '>= 4.2'
29
+ spec.add_dependency 'pg'
30
+ spec.add_dependency 'i18n'
31
+ end
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: translateable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Oleg Antonyan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activerecord
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '4.2'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '4.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '4.2'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '4.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pg
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: i18n
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: Similar to globalize, but uses PostgreSQL's JSONB to store data in a
126
+ single field. No additional tables required. Very thin abstraction
127
+ email:
128
+ - oleg.b.antonyan@gmail.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - ".rspec"
135
+ - ".rubocop.yml"
136
+ - ".travis.yml"
137
+ - CODE_OF_CONDUCT.md
138
+ - Gemfile
139
+ - LICENSE.txt
140
+ - README.md
141
+ - Rakefile
142
+ - bin/console
143
+ - bin/setup
144
+ - gemfiles/4.2.gemfile
145
+ - gemfiles/5.0.gemfile
146
+ - lib/generators/translateable/migration_generator.rb
147
+ - lib/generators/translateable/templates/migration.rb.erb
148
+ - lib/translateable.rb
149
+ - lib/translateable/version.rb
150
+ - translateable.gemspec
151
+ homepage: https://github.com/olegantonyan/translateable_data
152
+ licenses:
153
+ - MIT
154
+ metadata: {}
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubyforge_project:
171
+ rubygems_version: 2.5.1
172
+ signing_key:
173
+ specification_version: 4
174
+ summary: Allows to store text data in different languages.
175
+ test_files: []