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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +26 -22
  4. data/Rakefile +1 -14
  5. data/lib/generators/translation/templates/migration.rb +14 -0
  6. data/lib/generators/translation/templates/model.rb +8 -0
  7. data/lib/generators/translation/translation_generator.rb +25 -0
  8. data/lib/translatable_records/builder.rb +66 -0
  9. data/lib/translatable_records/concern.rb +22 -0
  10. data/lib/translatable_records/extensions/active_record/base.rb +26 -0
  11. data/lib/translatable_records/railtie.rb +4 -2
  12. data/lib/translatable_records/version.rb +1 -1
  13. data/lib/translatable_records.rb +4 -2
  14. data/test/dummy/Rakefile +1 -2
  15. data/test/dummy/app/assets/javascripts/application.js +2 -2
  16. data/test/dummy/app/assets/stylesheets/application.css +6 -4
  17. data/test/dummy/app/models/product.rb +5 -0
  18. data/test/dummy/app/models/product_translation.rb +8 -0
  19. data/test/dummy/app/views/layouts/application.html.erb +9 -11
  20. data/test/dummy/bin/bundle +1 -0
  21. data/test/dummy/bin/rails +2 -1
  22. data/test/dummy/bin/rake +1 -0
  23. data/test/dummy/bin/setup +30 -0
  24. data/test/dummy/config/application.rb +3 -0
  25. data/test/dummy/config/boot.rb +1 -1
  26. data/test/dummy/config/database.yml +4 -22
  27. data/test/dummy/config/database.yml.travis +3 -0
  28. data/test/dummy/config/environment.rb +1 -1
  29. data/test/dummy/config/environments/development.rb +15 -3
  30. data/test/dummy/config/environments/production.rb +21 -26
  31. data/test/dummy/config/environments/test.rb +10 -12
  32. data/test/dummy/config/initializers/assets.rb +11 -0
  33. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  34. data/test/dummy/config/initializers/mime_types.rb +1 -2
  35. data/test/dummy/config/initializers/session_store.rb +1 -1
  36. data/test/dummy/config/routes.rb +2 -2
  37. data/test/dummy/config/secrets.yml +22 -0
  38. data/test/dummy/config.ru +1 -1
  39. data/test/dummy/db/migrate/20130819155126_create_products.rb +8 -0
  40. data/test/dummy/db/migrate/20161205171056_create_product_translations.rb +12 -0
  41. data/test/dummy/db/schema.rb +13 -11
  42. data/test/dummy/log/development.log +39 -0
  43. data/test/dummy/log/test.log +1443 -62
  44. data/test/dummy/public/404.html +58 -55
  45. data/test/dummy/public/422.html +58 -55
  46. data/test/dummy/public/500.html +57 -54
  47. data/test/generator_test.rb +21 -0
  48. data/test/record_test.rb +38 -0
  49. data/test/test_helper.rb +5 -13
  50. metadata +42 -33
  51. data/lib/generators/templates/migration.rb +0 -12
  52. data/lib/generators/templates/model.rb +0 -8
  53. data/lib/generators/translation_generator.rb +0 -21
  54. data/lib/translatable_records/active_record/base.rb +0 -56
  55. data/lib/translatable_records/active_record/translatable.rb +0 -26
  56. data/test/dummy/README.rdoc +0 -28
  57. data/test/dummy/app/models/model.rb +0 -3
  58. data/test/dummy/app/models/model_translation.rb +0 -8
  59. data/test/dummy/config/initializers/secret_token.rb +0 -13
  60. data/test/dummy/db/migrate/20130819155126_create_models.rb +0 -8
  61. data/test/dummy/db/migrate/20130819165249_create_model_translations.rb +0 -13
  62. data/test/generators_test.rb +0 -19
  63. data/test/records_test.rb +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4228adff17f8b8ab53b85eef95a3be51440a541
4
- data.tar.gz: c1e619dddbbb566e976e8e48d39273f05678efe6
3
+ metadata.gz: 0aa7a3637f4a3e85e9a73392989ab14fb3b3256f
4
+ data.tar.gz: bee2ea776f4f3075ec6b14f65969485d29eeac94
5
5
  SHA512:
6
- metadata.gz: 9d776770cbb1a7cdf6d407809df5804714f5ee5516e1e587c19ad64b02adfc3c414b3ff8ab175f18780af4351db2d737728dedc81e1a9468e77fa81936021282
7
- data.tar.gz: 28c8cc5576f218722edc70e486d658d85a3cbfb26c3fca641bedf7cd98748162d4737568c74ef0750c29da2e5db15ebd602aa297c48a97fc6b563af7b91e67b8
6
+ metadata.gz: 9dd0bd41b405a1cd70f046903ab7229682c0b31bf5beb30d63f456cbf0fef69405e10b326fef5b897f678ac713d91ef6560b6b6640f2490d1645ff0432f209f2
7
+ data.tar.gz: 192a617012a83f7fe36357ce3bcf60953d6624255b1b290256ed1b70e49b4810cbad79cca3ad982b9da13fc49495567acbe9ace667caf3eaf79ba4adc573650a
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2015 Mathías Montossi
1
+ Copyright 2016 Mathías Montossi
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -5,7 +5,15 @@
5
5
 
6
6
  # Translatable Records
7
7
 
8
- Minimalistic toolkit to work with translatable records in rails.
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 translatable with the attr_translatable in your models:
32
+ Define wich attributes will be translated in the model:
25
33
  ```ruby
26
- attr_translatable :attr
34
+ class Product < ActiveRecord::Base
35
+ translate :name
36
+ end
27
37
  ```
28
38
 
29
- Generate the translation model and migration for them:
39
+ Generate the translation and migration:
30
40
  ```
31
- rails g translation model
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
- If you want to change the locale to something different than I18n.locale:
51
+ ### Accessors
52
+
53
+ By default will use I18n.locale but you can change it:
52
54
  ```ruby
53
- record.with_locale :es
55
+ product.locale = :en
54
56
  ```
55
57
 
56
- If you want to build a translation for each available locale:
58
+ Accessor continue working the same:
57
59
  ```ruby
58
- record.build_translations
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 :attr %>
66
- <%= ff.text_field :attr %>
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,8 @@
1
+ class <%= class_name %>Translation < ActiveRecord::Base
2
+
3
+ belongs_to :<%= singular_table_name %>
4
+
5
+ validates_presence_of :locale
6
+ validates_uniqueness_of :<%= singular_table_name %>_id, scope: :locale
7
+
8
+ 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.send :include, TranslatableRecords::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
@@ -1,5 +1,5 @@
1
1
  module TranslatableRecords
2
2
 
3
- VERSION = '1.1.7'
3
+ VERSION = '4.0.0.0'
4
4
 
5
5
  end
@@ -1,6 +1,8 @@
1
- require 'translatable_records/active_record/base'
2
- require 'translatable_records/active_record/translatable'
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,5 +2,4 @@
2
2
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
3
 
4
4
  require File.expand_path('../config/application', __FILE__)
5
-
6
- Dummy::Application.load_tasks
5
+ Rails.application.load_tasks
@@ -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 of plugins, if any, can be referenced here using a relative path.
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/sstephenson/sprockets#sprockets-directives) for details
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 of plugins, if any, can be referenced here using a relative path.
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 top of the
9
- * compiled file, but it's generally better to create a new file per style scope.
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
  */
@@ -0,0 +1,5 @@
1
+ class Product < ActiveRecord::Base
2
+
3
+ translate :name
4
+
5
+ end
@@ -0,0 +1,8 @@
1
+ class ProductTranslation < ActiveRecord::Base
2
+
3
+ belongs_to :product
4
+
5
+ validates_presence_of :locale
6
+ validates_uniqueness_of :product_id, scope: :locale
7
+
8
+ end
@@ -1,14 +1,12 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
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
-
11
- <%= yield %>
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>
@@ -1,3 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
+
2
3
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
4
  load Gem.bin_path('bundler', 'bundle')
data/test/dummy/bin/rails CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- APP_PATH = File.expand_path('../../config/application', __FILE__)
2
+
3
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
4
  require_relative '../config/boot'
4
5
  require 'rails/commands'
data/test/dummy/bin/rake CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+
2
3
  require_relative '../config/boot'
3
4
  require 'rake'
4
5
  Rake.application.run