translatable_records 1.1.7 → 4.0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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