mobility 0.4.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +27 -27
- data/README.md +8 -8
- data/lib/mobility.rb +18 -5
- data/lib/mobility/{wrapper.rb → accumulator.rb} +2 -4
- data/lib/mobility/active_record.rb +1 -0
- data/lib/mobility/active_record/backend_resetter.rb +1 -0
- data/lib/mobility/active_record/string_translation.rb +1 -0
- data/lib/mobility/active_record/text_translation.rb +1 -0
- data/lib/mobility/adapter.rb +19 -0
- data/lib/mobility/attributes.rb +2 -1
- data/lib/mobility/backend.rb +1 -1
- data/lib/mobility/backend/orm_delegator.rb +5 -4
- data/lib/mobility/backend_resetter.rb +2 -0
- data/lib/mobility/backends/active_record/column.rb +1 -0
- data/lib/mobility/backends/active_record/column/query_methods.rb +1 -0
- data/lib/mobility/backends/active_record/container.rb +21 -4
- data/lib/mobility/backends/active_record/container/json_query_methods.rb +30 -0
- data/lib/mobility/backends/active_record/container/{query_methods.rb → jsonb_query_methods.rb} +4 -2
- data/lib/mobility/backends/active_record/json.rb +36 -0
- data/lib/mobility/backends/active_record/json/query_methods.rb +25 -0
- data/lib/mobility/backends/active_record/jsonb.rb +4 -4
- data/lib/mobility/backends/active_record/jsonb/query_methods.rb +1 -0
- data/lib/mobility/backends/active_record/key_value.rb +2 -2
- data/lib/mobility/backends/active_record/key_value/query_methods.rb +1 -0
- data/lib/mobility/backends/active_record/pg_hash.rb +1 -0
- data/lib/mobility/backends/active_record/pg_query_methods.rb +1 -1
- data/lib/mobility/backends/active_record/serialized.rb +1 -0
- data/lib/mobility/backends/active_record/serialized/query_methods.rb +1 -0
- data/lib/mobility/backends/active_record/table.rb +2 -2
- data/lib/mobility/backends/active_record/table/query_methods.rb +1 -0
- data/lib/mobility/backends/column.rb +2 -0
- data/lib/mobility/backends/json.rb +20 -0
- data/lib/mobility/backends/jsonb.rb +0 -1
- data/lib/mobility/backends/key_value.rb +1 -0
- data/lib/mobility/backends/sequel/column.rb +1 -0
- data/lib/mobility/backends/sequel/column/query_methods.rb +1 -0
- data/lib/mobility/backends/sequel/container.rb +19 -3
- data/lib/mobility/backends/sequel/container/json_query_methods.rb +34 -0
- data/lib/mobility/backends/sequel/container/{query_methods.rb → jsonb_query_methods.rb} +2 -1
- data/lib/mobility/backends/sequel/hstore/query_methods.rb +1 -0
- data/lib/mobility/backends/sequel/json.rb +36 -0
- data/lib/mobility/backends/sequel/json/query_methods.rb +27 -0
- data/lib/mobility/backends/sequel/jsonb/query_methods.rb +2 -1
- data/lib/mobility/backends/sequel/key_value.rb +3 -3
- data/lib/mobility/backends/sequel/key_value/query_methods.rb +1 -0
- data/lib/mobility/backends/sequel/pg_hash.rb +1 -0
- data/lib/mobility/backends/sequel/query_methods.rb +1 -0
- data/lib/mobility/backends/sequel/serialized.rb +1 -0
- data/lib/mobility/backends/sequel/serialized/query_methods.rb +1 -0
- data/lib/mobility/backends/sequel/table.rb +1 -0
- data/lib/mobility/backends/sequel/table/query_methods.rb +1 -0
- data/lib/mobility/backends/serialized.rb +1 -0
- data/lib/mobility/backends/table.rb +1 -0
- data/lib/mobility/configuration.rb +3 -5
- data/lib/mobility/fallbacks.rb +28 -0
- data/lib/mobility/plugins/active_model/dirty.rb +5 -5
- data/lib/mobility/plugins/active_record/dirty.rb +1 -1
- data/lib/mobility/plugins/cache.rb +1 -0
- data/lib/mobility/plugins/default.rb +2 -0
- data/lib/mobility/plugins/dirty.rb +1 -0
- data/lib/mobility/plugins/fallbacks.rb +3 -1
- data/lib/mobility/plugins/fallthrough_accessors.rb +4 -4
- data/lib/mobility/plugins/locale_accessors.rb +2 -2
- data/lib/mobility/plugins/presence.rb +1 -0
- data/lib/mobility/sequel/column_changes.rb +3 -1
- data/lib/mobility/sequel/hash_initializer.rb +2 -0
- data/lib/mobility/sequel/string_translation.rb +1 -0
- data/lib/mobility/sequel/text_translation.rb +1 -0
- data/lib/mobility/translates.rb +2 -0
- data/lib/mobility/util.rb +3 -1
- data/lib/mobility/version.rb +3 -1
- data/lib/rails/generators/mobility/active_record_migration_compatibility.rb +1 -0
- data/lib/rails/generators/mobility/backend_generators/base.rb +3 -3
- data/lib/rails/generators/mobility/generators.rb +1 -0
- data/lib/rails/generators/mobility/install_generator.rb +1 -0
- data/lib/rails/generators/mobility/templates/initializer.rb +75 -0
- data/lib/rails/generators/mobility/translations_generator.rb +3 -3
- metadata +14 -5
- metadata.gz.sig +0 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'mobility/backends/active_record/pg_query_methods'
|
3
|
+
require "mobility/backends/active_record/query_methods"
|
4
|
+
|
5
|
+
module Mobility
|
6
|
+
module Backends
|
7
|
+
class ActiveRecord::Container::JsonQueryMethods < ActiveRecord::QueryMethods
|
8
|
+
include ActiveRecord::PgQueryMethods
|
9
|
+
attr_reader :column_name, :column
|
10
|
+
|
11
|
+
def initialize(_attributes, options)
|
12
|
+
super
|
13
|
+
@column_name = options[:column_name]
|
14
|
+
@column = arel_table[@column_name]
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def matches(key, value, locale)
|
20
|
+
build_infix(:'->>',
|
21
|
+
build_infix(:'->', column, quote(locale)),
|
22
|
+
quote(key)).eq(value && value.to_s)
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_locale(key, locale)
|
26
|
+
matches(key, nil, locale).not
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/mobility/backends/active_record/container/{query_methods.rb → jsonb_query_methods.rb}
RENAMED
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'mobility/backends/active_record/pg_query_methods'
|
3
|
+
require "mobility/backends/active_record/query_methods"
|
2
4
|
|
3
5
|
module Mobility
|
4
6
|
module Backends
|
5
|
-
class ActiveRecord::Container::
|
7
|
+
class ActiveRecord::Container::JsonbQueryMethods < ActiveRecord::QueryMethods
|
6
8
|
include ActiveRecord::PgQueryMethods
|
7
9
|
attr_reader :column_name, :column
|
8
10
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'mobility/backends/active_record/pg_hash'
|
2
|
+
|
3
|
+
module Mobility
|
4
|
+
module Backends
|
5
|
+
=begin
|
6
|
+
|
7
|
+
Implements the {Mobility::Backends::Json} backend for ActiveRecord models.
|
8
|
+
|
9
|
+
@see Mobility::Backends::ActiveRecord::HashValued
|
10
|
+
|
11
|
+
=end
|
12
|
+
class ActiveRecord::Json < ActiveRecord::PgHash
|
13
|
+
require 'mobility/backends/active_record/json/query_methods'
|
14
|
+
|
15
|
+
# @!group Backend Accessors
|
16
|
+
#
|
17
|
+
# @note Translation may be string, integer or boolean-valued since
|
18
|
+
# value is stored on a JSON hash.
|
19
|
+
# @param [Symbol] locale Locale to read
|
20
|
+
# @param [Hash] options
|
21
|
+
# @return [String,Integer,Boolean] Value of translation
|
22
|
+
# @!method read(locale, **options)
|
23
|
+
|
24
|
+
# @!group Backend Accessors
|
25
|
+
# @note Translation may be string, integer or boolean-valued since
|
26
|
+
# value is stored on a JSON hash.
|
27
|
+
# @param [Symbol] locale Locale to write
|
28
|
+
# @param [String,Integer,Boolean] value Value to write
|
29
|
+
# @param [Hash] options
|
30
|
+
# @return [String,Integer,Boolean] Updated value
|
31
|
+
# @!method write(locale, value, **options)
|
32
|
+
|
33
|
+
setup_query_methods(QueryMethods)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'mobility/backends/active_record/pg_query_methods'
|
3
|
+
require "mobility/backends/active_record/query_methods"
|
4
|
+
|
5
|
+
module Mobility
|
6
|
+
module Backends
|
7
|
+
class ActiveRecord::Json::QueryMethods < ActiveRecord::QueryMethods
|
8
|
+
include ActiveRecord::PgQueryMethods
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def matches(key, value, locale)
|
13
|
+
build_locale_infix(key, locale).eq(value.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def has_locale(key, locale)
|
17
|
+
build_locale_infix(key, locale).eq(nil).not
|
18
|
+
end
|
19
|
+
|
20
|
+
def build_locale_infix(key, locale)
|
21
|
+
build_infix(:'->>', arel_table[key], quote(locale))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -14,16 +14,16 @@ Implements the {Mobility::Backends::Jsonb} backend for ActiveRecord models.
|
|
14
14
|
|
15
15
|
# @!group Backend Accessors
|
16
16
|
#
|
17
|
-
# @note Translation may be
|
18
|
-
#
|
17
|
+
# @note Translation may be any json type, but querying will only work on
|
18
|
+
# string-typed values.
|
19
19
|
# @param [Symbol] locale Locale to read
|
20
20
|
# @param [Hash] options
|
21
21
|
# @return [String,Integer,Boolean] Value of translation
|
22
22
|
# @!method read(locale, **options)
|
23
23
|
|
24
24
|
# @!group Backend Accessors
|
25
|
-
# @note Translation may be
|
26
|
-
#
|
25
|
+
# @note Translation may be any json type, but querying will only work on
|
26
|
+
# string-typed values.
|
27
27
|
# @param [Symbol] locale Locale to write
|
28
28
|
# @param [String,Integer,Boolean] value Value to write
|
29
29
|
# @param [Hash] options
|
@@ -38,7 +38,7 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
|
|
38
38
|
def self.configure(options)
|
39
39
|
super
|
40
40
|
type = options[:type]
|
41
|
-
options[:class_name] ||= Mobility::ActiveRecord.const_get("#{type.capitalize}Translation"
|
41
|
+
options[:class_name] ||= Mobility::ActiveRecord.const_get("#{type.capitalize}Translation")
|
42
42
|
options[:class_name] = options[:class_name].constantize if options[:class_name].is_a?(String)
|
43
43
|
options[:association_name] ||= :"#{options[:type]}_translations"
|
44
44
|
%i[type association_name].each { |key| options[key] = options[key].to_sym }
|
@@ -103,7 +103,7 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
|
|
103
103
|
# Clean up *all* leftover translations of this model, only once.
|
104
104
|
def mobility_destroy_key_value_translations
|
105
105
|
[:string, :text].freeze.each do |type|
|
106
|
-
Mobility::ActiveRecord.const_get("#{type.capitalize}Translation"
|
106
|
+
Mobility::ActiveRecord.const_get("#{type.capitalize}Translation").
|
107
107
|
where(translatable: self).destroy_all
|
108
108
|
end
|
109
109
|
end
|
@@ -101,7 +101,7 @@ columns to that table.
|
|
101
101
|
# to append to model class to generate translation class
|
102
102
|
def self.configure(options)
|
103
103
|
table_name = options[:model_class].table_name
|
104
|
-
options[:table_name] ||= "#{table_name.singularize}_translations"
|
104
|
+
options[:table_name] ||= "#{table_name.singularize}_translations"
|
105
105
|
options[:foreign_key] ||= table_name.downcase.singularize.camelize.foreign_key
|
106
106
|
if (association_name = options[:association_name]).present?
|
107
107
|
options[:subclass_name] ||= association_name.to_s.singularize.camelize.freeze
|
@@ -158,7 +158,7 @@ columns to that table.
|
|
158
158
|
setup_query_methods(QueryMethods)
|
159
159
|
|
160
160
|
def translation_for(locale, _)
|
161
|
-
translation = translations.find { |t| t.locale == locale.to_s
|
161
|
+
translation = translations.find { |t| t.locale == locale.to_s }
|
162
162
|
translation ||= translations.build(locale: locale)
|
163
163
|
translation
|
164
164
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Mobility
|
2
|
+
module Backends
|
3
|
+
=begin
|
4
|
+
|
5
|
+
Stores translations as hash on Postgres json column.
|
6
|
+
|
7
|
+
==Backend Options
|
8
|
+
|
9
|
+
This backend has no options.
|
10
|
+
|
11
|
+
@see Mobility::Backends::ActiveRecord::Json
|
12
|
+
@see Mobility::Backends::Sequel::Json
|
13
|
+
@see https://www.postgresql.org/docs/current/static/datatype-json.html PostgreSQL Documentation for JSON Types
|
14
|
+
|
15
|
+
=end
|
16
|
+
module Json
|
17
|
+
extend Backend::OrmDelegator
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -8,7 +8,8 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
8
8
|
class Sequel::Container
|
9
9
|
include Sequel
|
10
10
|
|
11
|
-
require 'mobility/backends/sequel/container/
|
11
|
+
require 'mobility/backends/sequel/container/json_query_methods'
|
12
|
+
require 'mobility/backends/sequel/container/jsonb_query_methods'
|
12
13
|
|
13
14
|
# @return [Symbol] name of container column
|
14
15
|
attr_reader :column_name
|
@@ -47,6 +48,12 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
47
48
|
# @option options [Symbol] column_name (:translations) Name of column on which to store translations
|
48
49
|
def self.configure(options)
|
49
50
|
options[:column_name] ||= :translations
|
51
|
+
options[:column_name] = options[:column_name].to_sym
|
52
|
+
column_name, db_schema = options[:column_name], options[:model_class].db_schema
|
53
|
+
options[:column_type] = db_schema[column_name] && (db_schema[column_name][:db_type]).to_sym
|
54
|
+
unless %i[json jsonb].include?(options[:column_type])
|
55
|
+
raise InvalidColumnType, "#{options[:column_name]} must be a column of type json or jsonb"
|
56
|
+
end
|
50
57
|
end
|
51
58
|
# @!endgroup
|
52
59
|
#
|
@@ -57,6 +64,8 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
57
64
|
end
|
58
65
|
end
|
59
66
|
|
67
|
+
backend_class = self
|
68
|
+
|
60
69
|
setup do |attributes, options|
|
61
70
|
column_name = options[:column_name]
|
62
71
|
before_validation = Module.new do
|
@@ -73,9 +82,14 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
73
82
|
|
74
83
|
plugin :defaults_setter
|
75
84
|
attributes.each { |attribute| default_values[attribute.to_sym] = {} }
|
76
|
-
end
|
77
85
|
|
78
|
-
|
86
|
+
query_methods = backend_class.const_get("#{options[:column_type].capitalize}QueryMethods")
|
87
|
+
extend(Module.new do
|
88
|
+
define_method ::Mobility.query_method do
|
89
|
+
super().with_extend(query_methods.new(attributes, options))
|
90
|
+
end
|
91
|
+
end)
|
92
|
+
end
|
79
93
|
|
80
94
|
private
|
81
95
|
|
@@ -94,6 +108,8 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
94
108
|
end
|
95
109
|
translations[locale.to_s][attribute] = value
|
96
110
|
end
|
111
|
+
|
112
|
+
class InvalidColumnType < StandardError; end
|
97
113
|
end
|
98
114
|
end
|
99
115
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "mobility/backends/sequel/pg_query_methods"
|
3
|
+
require "mobility/backends/sequel/query_methods"
|
4
|
+
|
5
|
+
Sequel.extension :pg_json, :pg_json_ops
|
6
|
+
|
7
|
+
module Mobility
|
8
|
+
module Backends
|
9
|
+
class Sequel::Container::JsonQueryMethods < Sequel::QueryMethods
|
10
|
+
include Sequel::PgQueryMethods
|
11
|
+
attr_reader :column_name
|
12
|
+
|
13
|
+
def initialize(attributes, options)
|
14
|
+
super
|
15
|
+
@column_name = options[:column_name]
|
16
|
+
define_query_methods
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def matches(key, value, locale)
|
22
|
+
build_op(column_name)[locale].get_text(key.to_s) =~ value.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_locale(key, locale)
|
26
|
+
build_op(column_name)[locale].get_text(key.to_s) !~ nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_op(key)
|
30
|
+
::Sequel.pg_json_op(key)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "mobility/backends/sequel/pg_query_methods"
|
2
3
|
require "mobility/backends/sequel/query_methods"
|
3
4
|
|
@@ -5,7 +6,7 @@ Sequel.extension :pg_json, :pg_json_ops
|
|
5
6
|
|
6
7
|
module Mobility
|
7
8
|
module Backends
|
8
|
-
class Sequel::Container::
|
9
|
+
class Sequel::Container::JsonbQueryMethods < Sequel::QueryMethods
|
9
10
|
include Sequel::PgQueryMethods
|
10
11
|
attr_reader :column_name
|
11
12
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'mobility/backends/sequel/pg_hash'
|
2
|
+
|
3
|
+
module Mobility
|
4
|
+
module Backends
|
5
|
+
=begin
|
6
|
+
|
7
|
+
Implements the {Mobility::Backends::Json} backend for Sequel models.
|
8
|
+
|
9
|
+
@see Mobility::Backends::Sequel::HashValued
|
10
|
+
|
11
|
+
=end
|
12
|
+
class Sequel::Json < Sequel::PgHash
|
13
|
+
require 'mobility/backends/sequel/json/query_methods'
|
14
|
+
|
15
|
+
# @!group Backend Accessors
|
16
|
+
#
|
17
|
+
# @note Translation may be any json type, but querying will only work on
|
18
|
+
# string-typed values.
|
19
|
+
# @param [Symbol] locale Locale to read
|
20
|
+
# @param [Hash] options
|
21
|
+
# @return [String,Integer,Boolean] Value of translation
|
22
|
+
# @!method read(locale, **options)
|
23
|
+
|
24
|
+
# @!group Backend Accessors
|
25
|
+
# @note Translation may be any json type, but querying will only work on
|
26
|
+
# string-typed values.
|
27
|
+
# @param [Symbol] locale Locale to write
|
28
|
+
# @param [String,Integer,Boolean] value Value to write
|
29
|
+
# @param [Hash] options
|
30
|
+
# @return [String,Integer,Boolean] Updated value
|
31
|
+
# @!method write(locale, value, **options)
|
32
|
+
|
33
|
+
setup_query_methods(QueryMethods)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "mobility/backends/sequel/pg_query_methods"
|
3
|
+
require "mobility/backends/sequel/query_methods"
|
4
|
+
|
5
|
+
Sequel.extension :pg_json, :pg_json_ops
|
6
|
+
|
7
|
+
module Mobility
|
8
|
+
module Backends
|
9
|
+
class Sequel::Json::QueryMethods < Sequel::QueryMethods
|
10
|
+
include Sequel::PgQueryMethods
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def matches(key, value, locale)
|
15
|
+
build_op(key).get_text(locale) =~ value.to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def has_locale(key, locale)
|
19
|
+
build_op(key).get_text(locale) !~ nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_op(key)
|
23
|
+
::Sequel.pg_json_op(key)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|