mobility 0.8.8 → 1.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +56 -0
  5. data/Gemfile +52 -16
  6. data/Gemfile.lock +113 -52
  7. data/Guardfile +23 -1
  8. data/README.md +184 -92
  9. data/Rakefile +6 -4
  10. data/lib/mobility.rb +40 -166
  11. data/lib/mobility/active_record/translation.rb +1 -1
  12. data/lib/mobility/arel/nodes/pg_ops.rb +1 -1
  13. data/lib/mobility/backend.rb +19 -41
  14. data/lib/mobility/backends.rb +20 -0
  15. data/lib/mobility/backends/active_record.rb +4 -0
  16. data/lib/mobility/backends/active_record/column.rb +2 -0
  17. data/lib/mobility/backends/active_record/container.rb +4 -2
  18. data/lib/mobility/backends/active_record/hstore.rb +2 -0
  19. data/lib/mobility/backends/active_record/json.rb +2 -0
  20. data/lib/mobility/backends/active_record/jsonb.rb +2 -0
  21. data/lib/mobility/backends/active_record/key_value.rb +5 -3
  22. data/lib/mobility/backends/active_record/pg_hash.rb +1 -1
  23. data/lib/mobility/backends/active_record/serialized.rb +2 -0
  24. data/lib/mobility/backends/active_record/table.rb +5 -3
  25. data/lib/mobility/backends/column.rb +0 -6
  26. data/lib/mobility/backends/container.rb +2 -1
  27. data/lib/mobility/backends/hash.rb +39 -0
  28. data/lib/mobility/backends/hstore.rb +0 -1
  29. data/lib/mobility/backends/json.rb +0 -1
  30. data/lib/mobility/backends/jsonb.rb +0 -1
  31. data/lib/mobility/backends/key_value.rb +22 -14
  32. data/lib/mobility/backends/null.rb +2 -0
  33. data/lib/mobility/backends/sequel.rb +3 -0
  34. data/lib/mobility/backends/sequel/column.rb +2 -0
  35. data/lib/mobility/backends/sequel/container.rb +3 -1
  36. data/lib/mobility/backends/sequel/hstore.rb +2 -0
  37. data/lib/mobility/backends/sequel/json.rb +2 -0
  38. data/lib/mobility/backends/sequel/jsonb.rb +3 -1
  39. data/lib/mobility/backends/sequel/key_value.rb +8 -6
  40. data/lib/mobility/backends/sequel/serialized.rb +2 -0
  41. data/lib/mobility/backends/sequel/table.rb +5 -2
  42. data/lib/mobility/backends/serialized.rb +1 -3
  43. data/lib/mobility/backends/table.rb +14 -6
  44. data/lib/mobility/pluggable.rb +36 -0
  45. data/lib/mobility/plugin.rb +260 -0
  46. data/lib/mobility/plugins.rb +26 -25
  47. data/lib/mobility/plugins/active_model.rb +17 -0
  48. data/lib/mobility/plugins/active_model/cache.rb +26 -0
  49. data/lib/mobility/plugins/active_model/dirty.rb +310 -54
  50. data/lib/mobility/plugins/active_record.rb +34 -0
  51. data/lib/mobility/plugins/active_record/backend.rb +25 -0
  52. data/lib/mobility/plugins/active_record/cache.rb +28 -0
  53. data/lib/mobility/plugins/active_record/dirty.rb +72 -101
  54. data/lib/mobility/plugins/active_record/query.rb +48 -34
  55. data/lib/mobility/plugins/active_record/uniqueness_validation.rb +60 -0
  56. data/lib/mobility/plugins/attribute_methods.rb +28 -20
  57. data/lib/mobility/plugins/attributes.rb +70 -0
  58. data/lib/mobility/plugins/backend.rb +138 -0
  59. data/lib/mobility/plugins/backend_reader.rb +34 -0
  60. data/lib/mobility/plugins/cache.rb +59 -24
  61. data/lib/mobility/plugins/default.rb +22 -17
  62. data/lib/mobility/plugins/dirty.rb +12 -33
  63. data/lib/mobility/plugins/fallbacks.rb +51 -43
  64. data/lib/mobility/plugins/fallthrough_accessors.rb +26 -25
  65. data/lib/mobility/plugins/locale_accessors.rb +25 -35
  66. data/lib/mobility/plugins/presence.rb +28 -21
  67. data/lib/mobility/plugins/query.rb +8 -17
  68. data/lib/mobility/plugins/reader.rb +50 -0
  69. data/lib/mobility/plugins/sequel.rb +34 -0
  70. data/lib/mobility/plugins/sequel/backend.rb +25 -0
  71. data/lib/mobility/plugins/sequel/cache.rb +24 -0
  72. data/lib/mobility/plugins/sequel/dirty.rb +45 -32
  73. data/lib/mobility/plugins/sequel/query.rb +21 -6
  74. data/lib/mobility/plugins/writer.rb +44 -0
  75. data/lib/mobility/translations.rb +95 -0
  76. data/lib/mobility/version.rb +12 -1
  77. data/lib/rails/generators/mobility/templates/initializer.rb +95 -77
  78. metadata +51 -51
  79. metadata.gz.sig +0 -0
  80. data/lib/mobility/active_model.rb +0 -4
  81. data/lib/mobility/active_model/backend_resetter.rb +0 -26
  82. data/lib/mobility/active_record.rb +0 -23
  83. data/lib/mobility/active_record/backend_resetter.rb +0 -26
  84. data/lib/mobility/active_record/uniqueness_validator.rb +0 -60
  85. data/lib/mobility/attributes.rb +0 -324
  86. data/lib/mobility/backend/orm_delegator.rb +0 -44
  87. data/lib/mobility/backend_resetter.rb +0 -50
  88. data/lib/mobility/configuration.rb +0 -138
  89. data/lib/mobility/fallbacks.rb +0 -28
  90. data/lib/mobility/interface.rb +0 -0
  91. data/lib/mobility/loaded.rb +0 -4
  92. data/lib/mobility/plugins/active_record/attribute_methods.rb +0 -38
  93. data/lib/mobility/plugins/cache/translation_cacher.rb +0 -40
  94. data/lib/mobility/sequel.rb +0 -9
  95. data/lib/mobility/sequel/backend_resetter.rb +0 -23
  96. data/lib/mobility/translates.rb +0 -73
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 157698dc2cfdf847b956ae45dd3ff8c447800053b07b3b68bf848feefc8e690f
4
- data.tar.gz: b711720dae3e3eb480bcd630045daa56873b03f101b623b707c0eb8735b5936a
3
+ metadata.gz: d2cfc984b6de27771cbdbe1e7cba1864134d7008a3c07a75a4f890ca0007a956
4
+ data.tar.gz: b7ea3bc4122a9f536a58bd00dc18b8c47151168e39dc8b315bdc5ade77e6385b
5
5
  SHA512:
6
- metadata.gz: 22843bcb2a06b050a0b38fe76a970097ea0e1082c2095414419ad1f32fd980f21f7a9853bb471c18a9c6c8bb5786652b0f42e3a6577d17ae103257ddf19da0fe
7
- data.tar.gz: 0527fabbd7ed167e6431b8ce2bc9239cf99c13c6f0d2ac9e3074896423fa459453091b54471b43c74f17bbbc2c44af89452854c59313b071828eacc236940590
6
+ metadata.gz: 745a3462d4ca4b9fe9a392a2c38e95a3a59626c8d560a7eaa5eb3650320c02a2b88797fe16bb5a203a3f0e42a401f632fcf620a5dcc0cc6e1f579dcb132a6a8e
7
+ data.tar.gz: 54031f4838a210915a964b954289e435cd4280c663b24c5516b6050318c9a0551b9912d36c968a71c17ac9199d30f0edea40cd4441046f38d4085f5195c73606
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,7 +1,63 @@
1
1
  # Mobility Changelog
2
2
 
3
+ ## 1.0.0.alpha (unreleased)
4
+ - Default fallbacks plugin to `true` when enabled
5
+ ([#447](https://github.com/shioyama/mobility/pull/447))
6
+ - Remove `Mobility::Backend.method_name`
7
+ ([#400](https://github.com/shioyama/mobility/pull/400))
8
+ - Remove `translated_attribute_names` as alias for `mobility_attributes`
9
+ ([#402](https://github.com/shioyama/mobility/pull/402))
10
+ - Move `_backend` methods into `backend_reader` plugin
11
+ ([#403](https://github.com/shioyama/mobility/pull/403))
12
+ - Replace `Configuration#query_method` configuration with Query plugin option
13
+ ([#414](https://github.com/shioyama/mobility/pull/414))
14
+ - Remove `Mobility::Configuration#default_accessor_locales`. Use plugin option
15
+ to configure global default instead.
16
+ ([#424](https://github.com/shioyama/mobility/pull/424))
17
+ - Pass `model_class` to `Mobility::Backend#configure` via class method rather
18
+ than on options hash ([#429](https://github.com/shioyama/mobility/pull/429))
19
+ - Remove `Mobility.new_fallbacks` and `Configuration#fallbacks_generator`
20
+ ([#433](https://github.com/shioyama/mobility/pull/433))
21
+ - Rename `backend_name` to `backend`
22
+ ([#443](https://github.com/shioyama/mobility/pull/443))
23
+ - Remove `Configuration#accessor_method`
24
+ ([#450](https://github.com/shioyama/mobility/pull/450))
25
+ - Rename `Mobility::Attributes` to `Mobility::Translations`
26
+ - Remove `Mobility::Configuration` altogether
27
+ ([#452](https://github.com/shioyama/mobility/pull/452))
28
+
3
29
  ## 0.8
4
30
 
31
+ ### 0.8.13 (May 27, 2020)
32
+
33
+ * Fix fallthrough accessor method_missing not passing all options to super
34
+ ([#364](https://github.com/shioyama/mobility/pull/364),
35
+ [#384](https://github.com/shioyama/mobility/pull/384),
36
+ [#377](https://github.com/shioyama/mobility/pull/377), thanks
37
+ [doits](https://github.com/doits)!)
38
+
39
+ ### 0.8.12 (May 15, 2020)
40
+
41
+ (yanked)
42
+
43
+ ### 0.8.11 (May 14, 2020)
44
+ * Handle select with block
45
+ ([#359](https://github.com/shioyama/mobility/pull/359), thanks
46
+ [dlcmh](https://github.com/dlcmh)!)
47
+
48
+ ### 0.8.10 (February 11, 2020)
49
+ * Enforce case_sensitive comparison for Rails 6.1
50
+ ([#333](https://github.com/shioyama/mobility/pull/333), thanks [morozRed](https://github.com/morozRed)!)
51
+
52
+ ### 0.8.9 (October 25, 2019)
53
+ * Fix Dirty plugin to work with Rails 6
54
+ ([#343](https://github.com/shioyama/mobility/pull/343),
55
+ [#348](https://github.com/shioyama/mobility/pull/348),
56
+ [#352](https://github.com/shioyama/mobility/pull/352) on master branch, plus
57
+ [#351](https://github.com/shioyama/mobility/pull/351) to sync to 0-8-stable
58
+ branch). Summary of changes
59
+ [here](https://github.com/shioyama/mobility/pull/347#issuecomment-544742401).
60
+
5
61
  ### 0.8.8 (September 18, 2019)
6
62
  * Accept any number of arguments to `Arel::Visitors::Visitor#visit`
7
63
  ([#339](https://github.com/shioyama/mobility/pull/339)). (Thanks to
data/Gemfile CHANGED
@@ -3,37 +3,73 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in mobility.gemspec
4
4
  gemspec
5
5
 
6
+ orm, orm_version = ENV['ORM'], ENV['ORM_VERSION']
7
+
6
8
  group :development, :test do
7
- if ENV['ORM'] == 'active_record'
8
- if ENV['RAILS_VERSION'] == '5.0'
9
- gem 'activerecord', '>= 5.0', '< 5.1'
10
- elsif ENV['RAILS_VERSION'] == '4.2'
9
+ case orm
10
+ when 'active_record'
11
+ orm_version ||= '6.0'
12
+ case orm_version
13
+ when '4.2'
11
14
  gem 'activerecord', '>= 4.2.6', '< 5.0'
12
- elsif ENV['RAILS_VERSION'] == '5.1'
15
+ when '5.0'
16
+ gem 'activerecord', '>= 5.0', '< 5.1'
17
+ when '5.1'
13
18
  gem 'activerecord', '>= 5.1', '< 5.2'
14
- elsif ENV['RAILS_VERSION'] == 'latest'
15
- gem 'activerecord', '>= 6.0.0.beta1'
16
- else # Default is Rails 5.2
19
+ when '5.2'
17
20
  gem 'activerecord', '>= 5.2.0', '< 5.3'
18
21
  gem 'railties', '>= 5.2.0.rc2', '< 5.3'
22
+ when '6.0'
23
+ gem 'activerecord', '>= 6.0.0', '< 6.1'
24
+ when '6.1'
25
+ git 'https://github.com/rails/rails.git' do
26
+ gem 'activerecord'
27
+ gem 'activesupport'
28
+ end
29
+ else
30
+ raise ArgumentError, 'Invalid ActiveRecord version'
19
31
  end
20
- gem "generator_spec", '~> 0.9.4'
21
- elsif ENV['ORM'] == 'sequel'
22
- if ENV['SEQUEL_VERSION'] == '4'
32
+ when 'sequel'
33
+ orm_version ||= '5'
34
+ case orm_version
35
+ when '4'
23
36
  gem 'sequel', '>= 4.46.0', '< 5.0'
24
- else
37
+ when '5'
25
38
  gem 'sequel', '>= 5.0.0', '< 6.0.0'
39
+ else
40
+ raise ArgumentError, 'Invalid Sequel version'
26
41
  end
42
+ when nil, ''
43
+ else
44
+ raise ArgumentError, "Invalid ORM: #{orm}"
27
45
  end
28
46
 
29
- gem 'allocation_stats' if ENV['TEST_PERFORMANCE']
47
+ gem 'allocation_stats' if ENV['FEATURE'] == 'performance'
48
+
49
+ if ENV['FEATURE'] == 'rails'
50
+ gem 'rails'
51
+ gem 'generator_spec', '~> 0.9.4'
52
+ end
30
53
 
31
54
  platforms :ruby do
32
55
  gem 'guard-rspec'
33
56
  gem 'pry-byebug'
34
- gem 'sqlite3', '~> 1.3.6'
35
- gem 'mysql2', '~> 0.4.9'
36
- gem 'pg', '< 1.0'
57
+ case ENV['DB']
58
+ when 'sqlite3'
59
+ if orm == 'active_record' && orm_version < '5.2'
60
+ gem 'sqlite3', '~> 1.3.13'
61
+ else
62
+ gem 'sqlite3', '~> 1.4.1'
63
+ end
64
+ when 'mysql'
65
+ gem 'mysql2'
66
+ when 'postgres'
67
+ if orm == 'active_record' && orm_version < '5.0'
68
+ gem 'pg', '< 1.0'
69
+ else
70
+ gem 'pg'
71
+ end
72
+ end
37
73
  end
38
74
  end
39
75
 
@@ -1,22 +1,65 @@
1
+ GIT
2
+ remote: https://github.com/rails/rails.git
3
+ revision: 0a608bd987fde4f9bc5bcf4bcebdb181d199cf4f
4
+ specs:
5
+ actionpack (6.1.0.alpha)
6
+ actionview (= 6.1.0.alpha)
7
+ activesupport (= 6.1.0.alpha)
8
+ rack (~> 2.0, >= 2.0.9)
9
+ rack-test (>= 0.6.3)
10
+ rails-dom-testing (~> 2.0)
11
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
12
+ actionview (6.1.0.alpha)
13
+ activesupport (= 6.1.0.alpha)
14
+ builder (~> 3.1)
15
+ erubi (~> 1.4)
16
+ rails-dom-testing (~> 2.0)
17
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
18
+ activemodel (6.1.0.alpha)
19
+ activesupport (= 6.1.0.alpha)
20
+ activerecord (6.1.0.alpha)
21
+ activemodel (= 6.1.0.alpha)
22
+ activesupport (= 6.1.0.alpha)
23
+ activesupport (6.1.0.alpha)
24
+ concurrent-ruby (~> 1.0, >= 1.0.2)
25
+ i18n (>= 1.6, < 2)
26
+ minitest (>= 5.1)
27
+ tzinfo (~> 2.0)
28
+ zeitwerk (~> 2.3)
29
+ railties (6.1.0.alpha)
30
+ actionpack (= 6.1.0.alpha)
31
+ activesupport (= 6.1.0.alpha)
32
+ method_source
33
+ rake (>= 0.8.7)
34
+ thor (~> 1.0)
35
+
1
36
  PATH
2
37
  remote: .
3
38
  specs:
4
- mobility (1.0.alpha.1)
39
+ mobility (1.0.0.alpha)
5
40
  i18n (>= 0.6.10, < 2)
6
41
  request_store (~> 1.0)
7
42
 
8
43
  GEM
9
44
  remote: https://rubygems.org/
10
45
  specs:
11
- benchmark-ips (2.7.2)
12
- byebug (10.0.2)
13
- coderay (1.1.2)
14
- concurrent-ruby (1.0.5)
15
- database_cleaner (1.7.0)
16
- diff-lcs (1.3)
17
- ffi (1.9.25)
46
+ actionmailer (0.6.1)
47
+ actionpack (>= 0.9.5)
48
+ benchmark-ips (2.8.2)
49
+ builder (3.2.4)
50
+ byebug (11.1.3)
51
+ coderay (1.1.3)
52
+ concurrent-ruby (1.1.7)
53
+ crass (1.0.6)
54
+ database_cleaner (1.8.5)
55
+ diff-lcs (1.4.4)
56
+ erubi (1.9.0)
57
+ ffi (1.13.1)
18
58
  formatador (0.2.5)
19
- guard (2.14.2)
59
+ generator_spec (0.9.4)
60
+ activesupport (>= 3.0.0)
61
+ railties (>= 3.0.0)
62
+ guard (2.16.2)
20
63
  formatador (>= 0.2.4)
21
64
  listen (>= 2.7, < 4.0)
22
65
  lumberjack (>= 1.0.12, < 2.0)
@@ -30,69 +73,87 @@ GEM
30
73
  guard (~> 2.1)
31
74
  guard-compat (~> 1.1)
32
75
  rspec (>= 2.99.0, < 4.0)
33
- i18n (1.1.1)
76
+ i18n (1.8.5)
34
77
  concurrent-ruby (~> 1.0)
35
- listen (3.1.5)
36
- rb-fsevent (~> 0.9, >= 0.9.4)
37
- rb-inotify (~> 0.9, >= 0.9.7)
38
- ruby_dep (~> 1.2)
39
- lumberjack (1.0.13)
40
- method_source (0.9.0)
41
- mysql2 (0.4.10)
78
+ listen (3.2.1)
79
+ rb-fsevent (~> 0.10, >= 0.10.3)
80
+ rb-inotify (~> 0.9, >= 0.9.10)
81
+ loofah (2.7.0)
82
+ crass (~> 1.0.2)
83
+ nokogiri (>= 1.5.9)
84
+ lumberjack (1.2.7)
85
+ method_source (1.0.0)
86
+ mini_portile2 (2.4.0)
87
+ minitest (5.14.2)
42
88
  nenv (0.3.0)
43
- notiffany (0.1.1)
89
+ nokogiri (1.10.10)
90
+ mini_portile2 (~> 2.4.0)
91
+ notiffany (0.1.3)
44
92
  nenv (~> 0.1)
45
93
  shellany (~> 0.0)
46
- pg (0.21.0)
47
- pry (0.11.3)
48
- coderay (~> 1.1.0)
49
- method_source (~> 0.9.0)
50
- pry-byebug (3.6.0)
51
- byebug (~> 10.0)
52
- pry (~> 0.10)
53
- rack (2.0.5)
54
- rake (12.3.1)
55
- rb-fsevent (0.10.3)
56
- rb-inotify (0.9.10)
57
- ffi (>= 0.5.0, < 2)
58
- request_store (1.4.1)
94
+ pg (1.2.3)
95
+ pry (0.13.1)
96
+ coderay (~> 1.1)
97
+ method_source (~> 1.0)
98
+ pry-byebug (3.9.0)
99
+ byebug (~> 11.0)
100
+ pry (~> 0.13.0)
101
+ rack (2.2.3)
102
+ rack-test (1.1.0)
103
+ rack (>= 1.0, < 3)
104
+ rails (0.9.5)
105
+ actionmailer (>= 0.6.1)
106
+ actionpack (>= 1.4.0)
107
+ activerecord (>= 1.6.0)
108
+ rake (>= 0.4.15)
109
+ rails-dom-testing (2.0.3)
110
+ activesupport (>= 4.2.0)
111
+ nokogiri (>= 1.6)
112
+ rails-html-sanitizer (1.3.0)
113
+ loofah (~> 2.3)
114
+ rake (12.3.3)
115
+ rb-fsevent (0.10.4)
116
+ rb-inotify (0.10.1)
117
+ ffi (~> 1.0)
118
+ request_store (1.5.0)
59
119
  rack (>= 1.4)
60
- rspec (3.8.0)
61
- rspec-core (~> 3.8.0)
62
- rspec-expectations (~> 3.8.0)
63
- rspec-mocks (~> 3.8.0)
64
- rspec-core (3.8.0)
65
- rspec-support (~> 3.8.0)
66
- rspec-expectations (3.8.2)
120
+ rspec (3.9.0)
121
+ rspec-core (~> 3.9.0)
122
+ rspec-expectations (~> 3.9.0)
123
+ rspec-mocks (~> 3.9.0)
124
+ rspec-core (3.9.2)
125
+ rspec-support (~> 3.9.3)
126
+ rspec-expectations (3.9.2)
67
127
  diff-lcs (>= 1.2.0, < 2.0)
68
- rspec-support (~> 3.8.0)
69
- rspec-mocks (3.8.0)
128
+ rspec-support (~> 3.9.0)
129
+ rspec-mocks (3.9.1)
70
130
  diff-lcs (>= 1.2.0, < 2.0)
71
- rspec-support (~> 3.8.0)
72
- rspec-support (3.8.0)
73
- ruby_dep (1.5.0)
74
- sequel (5.20.0)
131
+ rspec-support (~> 3.9.0)
132
+ rspec-support (3.9.3)
75
133
  shellany (0.0.1)
76
- sqlite3 (1.3.13)
77
- thor (0.20.0)
78
- yard (0.9.16)
134
+ thor (1.0.1)
135
+ tzinfo (2.0.2)
136
+ concurrent-ruby (~> 1.0)
137
+ yard (0.9.25)
138
+ zeitwerk (2.4.0)
79
139
 
80
140
  PLATFORMS
81
141
  ruby
82
142
 
83
143
  DEPENDENCIES
144
+ activerecord!
145
+ activesupport!
84
146
  benchmark-ips
85
147
  database_cleaner (~> 1.5, >= 1.5.3)
148
+ generator_spec (~> 0.9.4)
86
149
  guard-rspec
87
150
  mobility!
88
- mysql2 (~> 0.4.9)
89
- pg (< 1.0)
151
+ pg
90
152
  pry-byebug
153
+ rails
91
154
  rake (~> 12, >= 12.2.1)
92
155
  rspec (~> 3.0)
93
- sequel (>= 5.0.0, < 6.0.0)
94
- sqlite3 (~> 1.3.6)
95
156
  yard (~> 0.9.0)
96
157
 
97
158
  BUNDLED WITH
98
- 1.17.3
159
+ 2.1.4
data/Guardfile CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  ## Uncomment and set this to only include directories you want to watch
5
5
  # directories %w(app lib config test spec features) \
6
- # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
6
+ # .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
7
 
8
8
  ## Note: if you are using the `directories` clause above and you are not
9
9
  ## watching the project directory ('.'), then you will want to move
@@ -40,6 +40,28 @@ guard :rspec, cmd: "bundle exec rspec" do
40
40
  ruby = dsl.ruby
41
41
  dsl.watch_spec_files_for(ruby.lib_files)
42
42
 
43
+ # Rails files
44
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
45
+ dsl.watch_spec_files_for(rails.app_files)
46
+ dsl.watch_spec_files_for(rails.views)
47
+
48
+ watch(rails.controllers) do |m|
49
+ [
50
+ rspec.spec.call("routing/#{m[1]}_routing"),
51
+ rspec.spec.call("controllers/#{m[1]}_controller"),
52
+ rspec.spec.call("acceptance/#{m[1]}")
53
+ ]
54
+ end
55
+
56
+ # Rails config changes
57
+ watch(rails.spec_helper) { rspec.spec_dir }
58
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ # Capybara features specs
62
+ watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
63
+ watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
64
+
43
65
  # Turnip features and steps
44
66
  watch(%r{^spec/acceptance/(.+)\.feature$})
45
67
  watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
data/README.md CHANGED
@@ -2,16 +2,22 @@ Mobility
2
2
  ========
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/mobility.svg)][gem]
5
- [![Build Status](https://travis-ci.org/shioyama/mobility.svg?branch=master)][travis]
5
+ [![Build Status](https://github.com/shioyama/mobility/workflows/CI/badge.svg)][actions]
6
6
  [![Code Climate](https://api.codeclimate.com/v1/badges/72200f2b00c339ec4537/maintainability.svg)][codeclimate]
7
7
  [![Gitter Chat](https://badges.gitter.im/mobility-ruby/mobility.svg)](https://gitter.im/mobility-ruby/mobility)
8
8
 
9
9
  [gem]: https://rubygems.org/gems/mobility
10
- [travis]: https://travis-ci.org/shioyama/mobility
10
+ [actions]: https://github.com/shioyama/mobility/actions
11
11
  [codeclimate]: https://codeclimate.com/github/shioyama/mobility
12
12
  [docs]: http://www.rubydoc.info/gems/mobility
13
13
  [wiki]: https://github.com/shioyama/mobility/wiki
14
14
 
15
+ **This is the readme for the [`master`](https://github.com/shioyama/mobility)
16
+ branch, which corresponds to v1.0.0.alpha, a pre-release version of Mobility.
17
+ If you are using an earlier version (0.8.x or earlier), you probably want the
18
+ readme on the [0-8-stable
19
+ branch](https://github.com/shioyama/mobility/tree/0-8-stable).**
20
+
15
21
  Mobility is a gem for storing and retrieving translations as attributes on a
16
22
  class. These translations could be the content of blog posts, captions on
17
23
  images, tags on bookmarks, or anything else you might want to store in
@@ -36,10 +42,10 @@ and [Sequel](http://sequel.jeremyevans.net/) ORM, with support for other
36
42
  platforms planned.
37
43
 
38
44
  For a detailed introduction to Mobility, see [Translating with
39
- Mobility](http://dejimata.com/2017/3/3/translating-with-mobility). See also the
40
- [Roadmap](https://github.com/shioyama/mobility/wiki/Roadmap) for what's in the
41
- works for future releases, and other pages of the [wiki][wiki] for more detail
42
- on usage.
45
+ Mobility](http://dejimata.com/2017/3/3/translating-with-mobility). See also my
46
+ talk at RubyConf 2018, [Building Generic
47
+ Software](https://www.youtube.com/watch?v=RZkemV_-__A), where I explain the
48
+ thinking behind Mobility's design.
43
49
 
44
50
  If you're coming from Globalize, be sure to also read the [Migrating from
45
51
  Globalize](https://github.com/shioyama/mobility/wiki/Migrating-from-Globalize)
@@ -48,31 +54,24 @@ section of the wiki.
48
54
  Installation
49
55
  ------------
50
56
 
51
- Add this line to your application's Gemfile:
57
+ To use the latest (unreleased) version of Mobility, add this line to your
58
+ application's Gemfile:
52
59
 
53
60
  ```ruby
54
- gem 'mobility', '~> 0.8.8'
55
- ```
56
-
57
- Mobility is cryptographically signed. To be sure the gem you install hasn't
58
- been tampered with, add my public key as a trusted certificate and install:
59
-
60
- ```
61
- gem cert --add <(curl -Ls https://raw.github.com/shioyama/mobility/master/certs/shioyama.pem)
62
- gem install mobility -P MediumSecurity
61
+ gem 'mobility', git: 'https://github.com/shioyama/mobility.git'
63
62
  ```
64
63
 
65
- The MediumSecurity trust profile will verify signed gems, but allow the
66
- installation of unsigned dependencies.
64
+ For the latest stable version of Mobility, see the readme on the
65
+ [0-8-stable](https://github.com/shioyama/mobility/tree/0-8-stable) branch.
67
66
 
68
67
  ### ActiveRecord (Rails)
69
68
 
70
69
  Requirements:
71
- - ActiveRecord >= 5.0
70
+ - ActiveRecord >= 5.0 (including 6.0)
72
71
 
73
72
  (Support for most backends and features is also supported with
74
73
  ActiveRecord/Rails 4.2, but there are some tests still failing. To see exactly
75
- what might not work, check pending specs in Rails 4.2 Travis builds.)
74
+ what might not work, check pending specs in Rails 4.2 builds.)
76
75
 
77
76
  To translate attributes on a model, extend `Mobility`, then call `translates`
78
77
  passing in one or more attributes as well as a hash of options (see below).
@@ -89,36 +88,52 @@ rails generate mobility:install
89
88
  the `--without_tables` option here to skip the migration generation.)
90
89
 
91
90
  The generator will create an initializer file `config/initializers/mobility.rb`
92
- with the lines:
91
+ which looks something like this:
93
92
 
94
93
  ```ruby
95
94
  Mobility.configure do |config|
96
- config.default_backend = :key_value
97
- config.accessor_method = :translates
98
- config.query_method = :i18n
95
+ # PLUGINS
96
+
97
+ config.plugins do
98
+ backend :key_value
99
+
100
+ active_record
101
+
102
+ reader
103
+ writer
104
+
105
+ # ...
106
+ end
99
107
  end
100
108
  ```
101
109
 
102
- To use a different default backend, set `default_backend` to another value (see
103
- possibilities [below](#backends)).
110
+ Each method call inside the block passed to `config.plugins` declares a plugin,
111
+ along with an optional default. To use a different default backend, you can
112
+ change the default passed to the `backend` plugin, like this:
113
+
114
+ ```diff
115
+ Mobility.configure do |config|
116
+ # PLUGINS
117
+
118
+ config.plugins do
119
+ - backend :key_value
120
+ + backend :table
121
+ ```
104
122
 
105
- You will likely also want to set default values for the various translation
106
- options described below. You can set these defaults by assigning values to keys
107
- on the `config.default_options` hash. Below, we turn on the Dirty plugin by
108
- default, so it will be enabled for all models.
123
+ See other possible backends in the [backends section](#backends).
109
124
 
110
125
  You can also set defaults for backend-specific options. Below, we set the
111
- default `type` option for the KeyValue backend to `:string` (this is
112
- unnecessary and will be ignored if you are using a different backend).
126
+ default `type` option for the KeyValue backend to `:string`.
113
127
 
114
128
  ```diff
115
129
  Mobility.configure do |config|
116
- config.default_backend = :key_value
117
- config.accessor_method = :translates
118
- config.query_method = :i18n
119
- + config.default_options[:dirty] = true
120
- + config.default_options[:type] = :string
121
- end
130
+ # PLUGINS
131
+
132
+ config.plugins do
133
+ - backend :key_value
134
+ + backend :key_value, type: :string
135
+ end
136
+ end
122
137
  ```
123
138
 
124
139
  We will assume the configuration above in the examples that follow. Other
@@ -132,6 +147,16 @@ See [Getting Started](#quickstart) to get started translating your models.
132
147
  Requirements:
133
148
  - Sequel >= 4.0
134
149
 
150
+ When configuring Mobility, ensure that you include the `sequel` plugin:
151
+
152
+ ```diff
153
+ config.plugins do
154
+ backend :key_value
155
+
156
+ - active_record
157
+ + sequel
158
+ ```
159
+
135
160
  You can extend `Mobility` just like in ActiveRecord, or you can use the
136
161
  `mobility` plugin, which does the same thing:
137
162
 
@@ -143,8 +168,8 @@ end
143
168
  ```
144
169
 
145
170
  Otherwise everything is (almost) identical to AR, with the exception that there
146
- is no equivalent to a Rails generator (so you will need to create the migration
147
- for any translation table(s) yourself, using Rails generators as a reference).
171
+ is no equivalent to a Rails generator, so you will need to create the migration
172
+ for any translation table(s) yourself, using Rails generators as a reference.
148
173
 
149
174
  The models in examples below all inherit from `ApplicationRecord`, but
150
175
  everything works exactly the same if the parent class is `Sequel::Model`.
@@ -259,15 +284,25 @@ changed and/or customized (see the [Backends](#backends) section below).
259
284
  ### <a name="getset"></a> Getting and Setting Translations
260
285
 
261
286
  The easiest way to get or set a translation is to use the getter and setter
262
- methods described above (`word.name` and `word.name=`), but you may want to
263
- access the value of an attribute in a specific locale, independent of the
264
- current value of `I18n.locale` (or `Mobility.locale`). There are a few ways to
265
- do this.
287
+ methods described above (`word.name` and `word.name=`), enabled by including
288
+ the `reader` and `writer` plugins.
289
+
290
+ You may also want to access the value of an attribute in a specific locale,
291
+ independent of the current value of `I18n.locale` (or `Mobility.locale`). There
292
+ are a few ways to do this.
266
293
 
267
294
  The first way is to define locale-specific methods, one for each locale you
268
295
  want to access directly on a given attribute. These are called "locale
269
- accessors" in Mobility, and they can be defined by passing a `locale_accessors`
270
- option when defining translated attributes on the model class:
296
+ accessors" in Mobility, and can be enabled by including the `locale_accessors`
297
+ plugin, with a default set of accessors:
298
+
299
+ ```diff
300
+ config.plugins do
301
+ # ...
302
+ + locale_accessors [:en, :ja]
303
+ ```
304
+
305
+ You can also override this default from `translates` in any model:
271
306
 
272
307
  ```ruby
273
308
  class Word < ApplicationRecord
@@ -296,24 +331,23 @@ word.name_ru
296
331
  #=> NoMethodError: undefined method `name_ru' for #<Word id: ... >
297
332
  ```
298
333
 
299
- To generate methods for all locales in `I18n.available_locales` (at the time
300
- the model is first loaded), use `locale_accessors: true`.
334
+ With no plugin option (or a default of `true`), Mobility generates methods for
335
+ all locales in `I18n.available_locales` at the time the model is first loaded.
301
336
 
302
- An alternative to using the `locale_accessors` option is to use the
303
- `fallthrough_accessors` option, with `fallthrough_accessors: true`. This uses
304
- Ruby's [`method_missing`](http://apidock.com/ruby/BasicObject/method_missing)
305
- method to implicitly define the same methods as above, but supporting any
306
- locale without any method definitions. (Locale accessors and fallthrough
307
- locales can be used together without conflict, with locale accessors taking
308
- precedence if defined for a given locale.)
337
+ An alternative to using the `locale_accessors` plugin is to use the
338
+ `fallthrough_accessors` plugin. This uses Ruby's
339
+ [`method_missing`](http://apidock.com/ruby/BasicObject/method_missing) method
340
+ to implicitly define the same methods as above, but supporting any locale
341
+ without any method definitions. (Locale accessors and fallthrough locales can
342
+ be used together without conflict, with locale accessors taking precedence if
343
+ defined for a given locale.)
309
344
 
310
- For example, if we define `Word` this way:
345
+ Ensure the plugin is enabled:
311
346
 
312
- ```ruby
313
- class Word < ApplicationRecord
314
- extend Mobility
315
- translates :name, fallthrough_accessors: true
316
- end
347
+ ```diff
348
+ config.plugins do
349
+ # ...
350
+ + fallthrough_accessors
317
351
  ```
318
352
 
319
353
  ... then we can access any locale we want, without specifying them upfront:
@@ -374,11 +408,24 @@ word.name_backend.read(:en)
374
408
  ```
375
409
 
376
410
  Internally, all methods for accessing translated attributes ultimately end up
377
- reading and writing from the backend instance this way.
411
+ reading and writing from the backend instance this way. (The `write` methods
412
+ do not call underlying backend's methods to persist the change. This is up to
413
+ the user, so e.g. with ActiveRecord you should call `save` write the changes to
414
+ the database).
378
415
 
379
- The `write` methods do not call underlying backend's methods to persist the change.
380
- This is up to the user (e.g. with ActiveRecord you should call `save` write
381
- the changes to the database).
416
+ Note that accessor methods are defined in an included module, so you can wrap
417
+ reads or writes in custom logic:
418
+
419
+ ```ruby
420
+ class Post < ApplicationRecord
421
+ extend Mobility
422
+ translates :title
423
+
424
+ def title(*)
425
+ super.reverse
426
+ end
427
+ end
428
+ ```
382
429
 
383
430
  ### Setting the Locale
384
431
 
@@ -419,15 +466,28 @@ details on how to configure it for your use case.
419
466
 
420
467
  ### <a name="fallbacks"></a>Fallbacks
421
468
 
422
- Mobility offers basic support for translation fallbacks. To enable fallbacks,
423
- pass a hash with fallbacks for each locale as an option when defining
469
+ Mobility offers basic support for translation fallbacks. First, enable the
470
+ `fallbacks` plugin:
471
+
472
+ ```diff
473
+ config.plugins do
474
+ # ...
475
+ + fallbacks
476
+ + locale_accessors
477
+ ```
478
+
479
+ Fallbacks will require `fallthrough_accessors` to handle methods like
480
+ `title_en`, which are used to track changes. For performance reasons it's
481
+ generally best to also enable the `locale_accessors` plugin as shown above.
482
+
483
+ Now pass a hash with fallbacks for each locale as an option when defining
424
484
  translated attributes on a class:
425
485
 
426
486
  ```ruby
427
487
  class Word < ApplicationRecord
428
488
  extend Mobility
429
- translates :name, fallbacks: { de: :ja, fr: :ja }, locale_accessors: true
430
- translates :meaning, fallbacks: { de: :ja, fr: :ja }, locale_accessors: true
489
+ translates :name, fallbacks: { de: :ja, fr: :ja }
490
+ translates :meaning, fallbacks: { de: :ja, fr: :ja }
431
491
  end
432
492
  ```
433
493
 
@@ -516,7 +576,16 @@ fallbacks](https://github.com/svenfuchs/i18n/wiki/Fallbacks).
516
576
 
517
577
  ### <a name="default"></a>Default values
518
578
 
519
- Another option is to assign a default value, which will be used if the result of a fetch would otherwise be `nil`:
579
+ Another option is to assign a default value, using the `default` plugin:
580
+
581
+ ```diff
582
+ config.plugins do
583
+ # ...
584
+ + default 'foo'
585
+ ```
586
+
587
+ Here we've set a "default default" of `'foo'`, which will be returned if a fetch would
588
+ otherwise return `nil`. This can be overridden from model classes:
520
589
 
521
590
  ```ruby
522
591
  class Word < ApplicationRecord
@@ -558,24 +627,29 @@ support it. Currently this is models which include
558
627
  [dirty](http://sequel.jeremyevans.net/rdoc-plugins/classes/Sequel/Plugins/Dirty.html)
559
628
  plugin).
560
629
 
561
- Enabling dirty tracking is as simple as sending the `dirty: true` option when
562
- defining a translated attribute. The way dirty tracking works is somewhat
563
- dependent on the model class (ActiveModel or Sequel); we will describe the
564
- ActiveModel implementation here.
630
+ First, ensure the `dirty` plugin is enabled in your configuration, and that you
631
+ have enabled an ORM plugin (either `active_record` or `sequel`), since the
632
+ dirty plugin will depend on one of these being enabled.
633
+
634
+ ```diff
635
+ config.plugins do
636
+ # ...
637
+ active_record
638
+ + dirty
639
+ ```
640
+
641
+ (Once enabled globally, the dirty plugin can be selectively disabled on classes
642
+ by passing `dirty: false` to `translates`.)
565
643
 
566
- First, enable dirty tracking (note that this is a persisted AR model, although
567
- dirty tracking is not specific to AR and works for non-persisted models as well):
644
+ Take this ActiveRecord class:
568
645
 
569
646
  ```ruby
570
647
  class Post < ApplicationRecord
571
648
  extend Mobility
572
- translates :title, dirty: true
649
+ translates :title
573
650
  end
574
651
  ```
575
652
 
576
- (If you want to enable dirty tracking on all models, set the
577
- `config.default_options[:dirty]` option in your Mobility configuration.)
578
-
579
653
  Let's assume we start with a post with a title in English and Japanese:
580
654
 
581
655
  ```ruby
@@ -637,9 +711,6 @@ For performance reasons, it is highly recommended that when using the Dirty
637
711
  plugin, you also enable [locale accessors](#getset) for all locales which will
638
712
  be used, so that methods like `title_en` above are defined; otherwise they will
639
713
  be caught by `method_missing` (using fallthrough accessors), which is much slower.
640
- The easiest way to do this is to set `config.default_options[:locale_accessors]
641
- = true` in your Mobility config, and make sure that `I18n.available_locales`
642
- includes all locales you use in production.
643
714
 
644
715
  For more details on dirty tracking, see the [API
645
716
  documentation](http://www.rubydoc.info/gems/mobility/Mobility/Plugins/Dirty).
@@ -647,9 +718,17 @@ documentation](http://www.rubydoc.info/gems/mobility/Mobility/Plugins/Dirty).
647
718
  ### Cache
648
719
 
649
720
  The Mobility cache caches localized values that have been fetched once so they
650
- can be quickly retrieved again. The cache is enabled by default and should
651
- generally only be disabled when debugging; this can be done by passing `cache:
652
- false` when defining an attribute, like this:
721
+ can be quickly retrieved again. The cache plugin is included in the default
722
+ configuration created by the install generator:
723
+
724
+ ```diff
725
+ config.plugins do
726
+ # ...
727
+ + cache
728
+ ```
729
+
730
+ It can be disabled selectively per model by passing `cache: false` when
731
+ defining an attribute, like this:
653
732
 
654
733
  ```ruby
655
734
  class Word < ApplicationRecord
@@ -659,7 +738,8 @@ end
659
738
  ```
660
739
 
661
740
  You can also turn off the cache for a single fetch by passing `cache: false` to
662
- the getter method, i.e. `post.title(cache: false)`.
741
+ the getter method, i.e. `post.title(cache: false)`. To remove the cache plugin
742
+ entirely, remove the `cache` line from the global plugins configuration.
663
743
 
664
744
  The cache is normally just a hash with locale keys and string (translation)
665
745
  values, but some backends (e.g. KeyValue and Table backends) have slightly more
@@ -667,11 +747,23 @@ complex implementations.
667
747
 
668
748
  ### <a name="querying"></a>Querying
669
749
 
670
- Mobility backends also support querying on translated attributes, in two
671
- different ways. The first is via query methods like `where` (and `not` and
672
- `find_by` in ActiveRecord, and `except` in Sequel). To query this way, use the
673
- `i18n` class method, which will return a model relation or dataset extended
674
- with Mobility-specific query method overrides.
750
+ Mobility backends also support querying on translated attributes. To enable
751
+ this feature, include the `query` plugin, and ensure you also have an ORM
752
+ plugin enabled (`active_record` or `sequel`):
753
+
754
+ ```diff
755
+ config.plugins do
756
+ # ...
757
+ active_record
758
+ + query
759
+ ```
760
+
761
+ Querying defines a scope or dataset class method, whose default name is `i18n`.
762
+ You can override this by passing a default in the configuration, like
763
+ `query :t` to use a name `t`.
764
+
765
+ Querying is supported in two different ways. The first is via query methods
766
+ like `where` (and `not` and `find_by` in ActiveRecord, and `except` in Sequel).
675
767
 
676
768
  So for ActiveRecord, assuming a model using KeyValue as its default backend:
677
769