translatable_records 1.1.7 → 4.0.0.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 +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +26 -22
- data/Rakefile +1 -14
- data/lib/generators/translation/templates/migration.rb +14 -0
- data/lib/generators/translation/templates/model.rb +8 -0
- data/lib/generators/translation/translation_generator.rb +25 -0
- data/lib/translatable_records/builder.rb +66 -0
- data/lib/translatable_records/concern.rb +22 -0
- data/lib/translatable_records/extensions/active_record/base.rb +26 -0
- data/lib/translatable_records/railtie.rb +4 -2
- data/lib/translatable_records/version.rb +1 -1
- data/lib/translatable_records.rb +4 -2
- data/test/dummy/Rakefile +1 -2
- data/test/dummy/app/assets/javascripts/application.js +2 -2
- data/test/dummy/app/assets/stylesheets/application.css +6 -4
- data/test/dummy/app/models/product.rb +5 -0
- data/test/dummy/app/models/product_translation.rb +8 -0
- data/test/dummy/app/views/layouts/application.html.erb +9 -11
- data/test/dummy/bin/bundle +1 -0
- data/test/dummy/bin/rails +2 -1
- data/test/dummy/bin/rake +1 -0
- data/test/dummy/bin/setup +30 -0
- data/test/dummy/config/application.rb +3 -0
- data/test/dummy/config/boot.rb +1 -1
- data/test/dummy/config/database.yml +4 -22
- data/test/dummy/config/database.yml.travis +3 -0
- data/test/dummy/config/environment.rb +1 -1
- data/test/dummy/config/environments/development.rb +15 -3
- data/test/dummy/config/environments/production.rb +21 -26
- data/test/dummy/config/environments/test.rb +10 -12
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/mime_types.rb +1 -2
- data/test/dummy/config/initializers/session_store.rb +1 -1
- data/test/dummy/config/routes.rb +2 -2
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +1 -1
- data/test/dummy/db/migrate/20130819155126_create_products.rb +8 -0
- data/test/dummy/db/migrate/20161205171056_create_product_translations.rb +12 -0
- data/test/dummy/db/schema.rb +13 -11
- data/test/dummy/log/development.log +39 -0
- data/test/dummy/log/test.log +1443 -62
- data/test/dummy/public/404.html +58 -55
- data/test/dummy/public/422.html +58 -55
- data/test/dummy/public/500.html +57 -54
- data/test/generator_test.rb +21 -0
- data/test/record_test.rb +38 -0
- data/test/test_helper.rb +5 -13
- metadata +42 -33
- data/lib/generators/templates/migration.rb +0 -12
- data/lib/generators/templates/model.rb +0 -8
- data/lib/generators/translation_generator.rb +0 -21
- data/lib/translatable_records/active_record/base.rb +0 -56
- data/lib/translatable_records/active_record/translatable.rb +0 -26
- data/test/dummy/README.rdoc +0 -28
- data/test/dummy/app/models/model.rb +0 -3
- data/test/dummy/app/models/model_translation.rb +0 -8
- data/test/dummy/config/initializers/secret_token.rb +0 -13
- data/test/dummy/db/migrate/20130819155126_create_models.rb +0 -8
- data/test/dummy/db/migrate/20130819165249_create_model_translations.rb +0 -13
- data/test/generators_test.rb +0 -19
- data/test/records_test.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0aa7a3637f4a3e85e9a73392989ab14fb3b3256f
|
4
|
+
data.tar.gz: bee2ea776f4f3075ec6b14f65969485d29eeac94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9dd0bd41b405a1cd70f046903ab7229682c0b31bf5beb30d63f456cbf0fef69405e10b326fef5b897f678ac713d91ef6560b6b6640f2490d1645ff0432f209f2
|
7
|
+
data.tar.gz: 192a617012a83f7fe36357ce3bcf60953d6624255b1b290256ed1b70e49b4810cbad79cca3ad982b9da13fc49495567acbe9ace667caf3eaf79ba4adc573650a
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -5,7 +5,15 @@
|
|
5
5
|
|
6
6
|
# Translatable Records
|
7
7
|
|
8
|
-
|
8
|
+
Fully customizable record translations for rails.
|
9
|
+
|
10
|
+
## Why
|
11
|
+
|
12
|
+
I did this gem to:
|
13
|
+
|
14
|
+
- Have the freedom to customize the translation model.
|
15
|
+
- Avoid duplication by delegate translatable attributes directly to translation model.
|
16
|
+
- Use translations other than I18n.available_locales.
|
9
17
|
|
10
18
|
## Install
|
11
19
|
|
@@ -21,49 +29,45 @@ $ bundle
|
|
21
29
|
|
22
30
|
## Configuration
|
23
31
|
|
24
|
-
Define wich attributes will be
|
32
|
+
Define wich attributes will be translated in the model:
|
25
33
|
```ruby
|
26
|
-
|
34
|
+
class Product < ActiveRecord::Base
|
35
|
+
translate :name
|
36
|
+
end
|
27
37
|
```
|
28
38
|
|
29
|
-
Generate the translation
|
39
|
+
Generate the translation and migration:
|
30
40
|
```
|
31
|
-
rails g translation
|
32
|
-
```
|
33
|
-
|
34
|
-
Complete the migrations adding the columns for each field in the translatations tables:
|
35
|
-
```ruby
|
36
|
-
add_column :model_translations, :attr, :string
|
37
|
-
```
|
38
|
-
|
39
|
-
Remove the original column from models table:
|
40
|
-
```ruby
|
41
|
-
remove_column :models, :attr
|
41
|
+
$ bundle exec rails g translation product
|
42
42
|
```
|
43
43
|
|
44
44
|
Update your db:
|
45
45
|
```
|
46
|
-
rake db:migrate
|
46
|
+
$ bundle exec rake db:migrate
|
47
47
|
```
|
48
48
|
|
49
49
|
## Usage
|
50
50
|
|
51
|
-
|
51
|
+
### Accessors
|
52
|
+
|
53
|
+
By default will use I18n.locale but you can change it:
|
52
54
|
```ruby
|
53
|
-
|
55
|
+
product.locale = :en
|
54
56
|
```
|
55
57
|
|
56
|
-
|
58
|
+
Accessor continue working the same:
|
57
59
|
```ruby
|
58
|
-
|
60
|
+
product.name = 'Phone'
|
59
61
|
```
|
60
62
|
|
63
|
+
### Views
|
64
|
+
|
61
65
|
If you want to save multiple translations:
|
62
66
|
```erb
|
63
67
|
<%= f.fields_for :translations do |ff| %>
|
64
68
|
<%= ff.hidden_field :locale %>
|
65
|
-
<%= ff.label :
|
66
|
-
<%= ff.text_field :
|
69
|
+
<%= ff.label :name %>
|
70
|
+
<%= ff.text_field :name %>
|
67
71
|
<% end %>
|
68
72
|
```
|
69
73
|
|
data/Rakefile
CHANGED
@@ -4,19 +4,6 @@ rescue LoadError
|
|
4
4
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
5
|
end
|
6
6
|
|
7
|
-
require 'rdoc/task'
|
8
|
-
|
9
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
-
rdoc.rdoc_dir = 'rdoc'
|
11
|
-
rdoc.title = 'TranslatableRecords'
|
12
|
-
rdoc.options << '--line-numbers'
|
13
|
-
rdoc.rdoc_files.include('README.rdoc')
|
14
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
7
|
Bundler::GemHelper.install_tasks
|
21
8
|
|
22
9
|
require 'rake/testtask'
|
@@ -26,7 +13,7 @@ Rake::TestTask.new(:test) do |t|
|
|
26
13
|
t.libs << 'test'
|
27
14
|
t.pattern = 'test/**/*_test.rb'
|
28
15
|
t.verbose = false
|
16
|
+
t.warning = false
|
29
17
|
end
|
30
18
|
|
31
|
-
|
32
19
|
task default: :test
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Create<%= class_name %>Translations < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :<%= singular_table_name %>_translations do |t|
|
4
|
+
t.integer :<%= singular_table_name %>_id
|
5
|
+
t.string :locale
|
6
|
+
<%- @attributes.each do |attribute| -%>
|
7
|
+
t.string :<%= attribute %>
|
8
|
+
<%- end -%>
|
9
|
+
|
10
|
+
t.timestamps null: false
|
11
|
+
end
|
12
|
+
add_index :<%= singular_table_name %>_translations, [:<%= singular_table_name %>_id, :locale], unique: true
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module TranslatableRecords
|
4
|
+
module Generators
|
5
|
+
class TranslationGenerator < ::Rails::Generators::NamedBase
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
9
|
+
|
10
|
+
def create_model_file
|
11
|
+
template 'model.rb', "app/models/#{singular_table_name}_translation.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_migration_file
|
15
|
+
@attributes = class_name.constantize.translations
|
16
|
+
migration_template 'migration.rb', "db/migrate/create_#{singular_table_name}_translations.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.next_migration_number(path)
|
20
|
+
Time.now.utc.strftime '%Y%m%d%H%M%S'
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module TranslatableRecords
|
2
|
+
class Builder
|
3
|
+
|
4
|
+
attr_reader :model, :concern
|
5
|
+
|
6
|
+
def initialize(model)
|
7
|
+
@model = model
|
8
|
+
@concern = Module.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def define(attributes)
|
12
|
+
model.include Concern
|
13
|
+
ensure_association
|
14
|
+
attributes.each do |attribute|
|
15
|
+
define_writer attribute
|
16
|
+
define_readers attribute
|
17
|
+
model.translations << attribute
|
18
|
+
end
|
19
|
+
model.include concern
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def ensure_association
|
25
|
+
unless model.reflections.has_key?(:translations)
|
26
|
+
model.has_many(
|
27
|
+
:translations,
|
28
|
+
class_name: "#{model.name}Translation",
|
29
|
+
dependent: :destroy
|
30
|
+
)
|
31
|
+
model.accepts_nested_attributes_for :translations
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def define_writer(attribute)
|
36
|
+
name = "#{attribute}="
|
37
|
+
concern.class_eval do
|
38
|
+
define_method name do |value|
|
39
|
+
if translation = find_translation(locale)
|
40
|
+
translation.send name, value
|
41
|
+
else
|
42
|
+
translations.build(locale: locale, attribute => value)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def define_readers(attribute)
|
49
|
+
names = [
|
50
|
+
attribute,
|
51
|
+
"#{attribute}_was",
|
52
|
+
"#{attribute}_changed?",
|
53
|
+
"#{attribute}_before_type_cast",
|
54
|
+
"#{attribute}_came_from_user?"
|
55
|
+
]
|
56
|
+
concern.class_eval do
|
57
|
+
names.each do |name|
|
58
|
+
define_method name do
|
59
|
+
find_translation(locale).try name
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module TranslatableRecords
|
2
|
+
module Concern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def locale=(value)
|
6
|
+
if value.present?
|
7
|
+
@locale = value.to_s
|
8
|
+
else
|
9
|
+
@locale = nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def locale
|
14
|
+
@locale || I18n.locale.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_translation(locale)
|
18
|
+
translations.to_a.group_by(&:locale)[locale.to_s].try :first
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module TranslatableRecords
|
2
|
+
module Extensions
|
3
|
+
module ActiveRecord
|
4
|
+
module Base
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
def translatable?
|
10
|
+
translations.any?
|
11
|
+
end
|
12
|
+
|
13
|
+
def translations
|
14
|
+
@translations ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
def translate(*attributes)
|
18
|
+
builder = Builder.new(self)
|
19
|
+
builder.define attributes
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module TranslatableRecords
|
2
2
|
class Railtie < Rails::Railtie
|
3
3
|
|
4
|
-
initializer 'translatable_records' do
|
5
|
-
::ActiveRecord::Base.
|
4
|
+
initializer 'translatable_records.extensions' do
|
5
|
+
::ActiveRecord::Base.include(
|
6
|
+
TranslatableRecords::Extensions::ActiveRecord::Base
|
7
|
+
)
|
6
8
|
end
|
7
9
|
|
8
10
|
end
|
data/lib/translatable_records.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
require 'translatable_records/active_record/base'
|
2
|
-
require 'translatable_records/
|
1
|
+
require 'translatable_records/extensions/active_record/base'
|
2
|
+
require 'translatable_records/builder'
|
3
|
+
require 'translatable_records/concern'
|
3
4
|
require 'translatable_records/railtie'
|
5
|
+
require 'translatable_records/version'
|
4
6
|
|
5
7
|
module TranslatableRecords
|
6
8
|
end
|
data/test/dummy/Rakefile
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
// listed below.
|
3
3
|
//
|
4
4
|
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
-
// or vendor/assets/javascripts
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
6
|
//
|
7
7
|
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
8
|
// compiled file.
|
9
9
|
//
|
10
|
-
// Read Sprockets README (https://github.com/
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
11
|
// about supported directives.
|
12
12
|
//
|
13
13
|
//= require_tree .
|
@@ -3,11 +3,13 @@
|
|
3
3
|
* listed below.
|
4
4
|
*
|
5
5
|
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
-
* or vendor/assets/stylesheets
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
7
|
*
|
8
|
-
* You're free to add application-wide styles to this file and they'll appear at the
|
9
|
-
* compiled file
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
10
12
|
*
|
11
|
-
*= require_self
|
12
13
|
*= require_tree .
|
14
|
+
*= require_self
|
13
15
|
*/
|
@@ -1,14 +1,12 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
|
-
<head>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
</head>
|
9
|
-
<body>
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
</body>
|
3
|
+
<head>
|
4
|
+
<title>Dummy</title>
|
5
|
+
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
|
6
|
+
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<%= yield %>
|
11
|
+
</body>
|
14
12
|
</html>
|
data/test/dummy/bin/bundle
CHANGED
data/test/dummy/bin/rails
CHANGED