mobility 0.8.10 → 1.0.0.beta2
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +66 -0
- data/Gemfile +50 -18
- data/Gemfile.lock +36 -101
- data/README.md +183 -91
- data/Rakefile +6 -4
- data/lib/mobility.rb +44 -166
- data/lib/mobility/arel.rb +1 -1
- data/lib/mobility/arel/nodes/pg_ops.rb +1 -1
- data/lib/mobility/backend.rb +27 -51
- data/lib/mobility/backends.rb +20 -0
- data/lib/mobility/backends/active_record.rb +4 -0
- data/lib/mobility/backends/active_record/column.rb +2 -0
- data/lib/mobility/backends/active_record/container.rb +6 -7
- data/lib/mobility/backends/active_record/hstore.rb +3 -1
- data/lib/mobility/backends/active_record/json.rb +2 -0
- data/lib/mobility/backends/active_record/jsonb.rb +2 -0
- data/lib/mobility/backends/active_record/key_value.rb +6 -4
- data/lib/mobility/backends/active_record/pg_hash.rb +1 -1
- data/lib/mobility/backends/active_record/serialized.rb +6 -0
- data/lib/mobility/backends/active_record/table.rb +6 -4
- data/lib/mobility/backends/column.rb +0 -6
- data/lib/mobility/backends/container.rb +10 -1
- data/lib/mobility/backends/hash.rb +39 -0
- data/lib/mobility/backends/hash_valued.rb +4 -0
- data/lib/mobility/backends/hstore.rb +0 -1
- data/lib/mobility/backends/json.rb +0 -1
- data/lib/mobility/backends/jsonb.rb +1 -2
- data/lib/mobility/backends/key_value.rb +31 -26
- data/lib/mobility/backends/null.rb +2 -0
- data/lib/mobility/backends/sequel.rb +5 -2
- data/lib/mobility/backends/sequel/column.rb +2 -0
- data/lib/mobility/backends/sequel/container.rb +6 -6
- data/lib/mobility/backends/sequel/hstore.rb +3 -1
- data/lib/mobility/backends/sequel/json.rb +3 -0
- data/lib/mobility/backends/sequel/jsonb.rb +3 -1
- data/lib/mobility/backends/sequel/key_value.rb +8 -6
- data/lib/mobility/backends/sequel/serialized.rb +6 -0
- data/lib/mobility/backends/sequel/table.rb +5 -2
- data/lib/mobility/backends/serialized.rb +1 -3
- data/lib/mobility/backends/table.rb +29 -26
- data/lib/mobility/pluggable.rb +56 -0
- data/lib/mobility/plugin.rb +260 -0
- data/lib/mobility/plugins.rb +27 -24
- data/lib/mobility/plugins/active_model.rb +17 -0
- data/lib/mobility/plugins/active_model/cache.rb +26 -0
- data/lib/mobility/plugins/active_model/dirty.rb +119 -78
- data/lib/mobility/plugins/active_record.rb +34 -0
- data/lib/mobility/plugins/active_record/backend.rb +25 -0
- data/lib/mobility/plugins/active_record/cache.rb +28 -0
- data/lib/mobility/plugins/active_record/dirty.rb +34 -17
- data/lib/mobility/plugins/active_record/query.rb +48 -34
- data/lib/mobility/plugins/active_record/uniqueness_validation.rb +60 -0
- data/lib/mobility/plugins/attribute_methods.rb +29 -20
- data/lib/mobility/plugins/attributes.rb +72 -0
- data/lib/mobility/plugins/backend.rb +161 -0
- data/lib/mobility/plugins/backend_reader.rb +34 -0
- data/lib/mobility/plugins/cache.rb +68 -26
- data/lib/mobility/plugins/default.rb +22 -17
- data/lib/mobility/plugins/dirty.rb +12 -33
- data/lib/mobility/plugins/fallbacks.rb +52 -44
- data/lib/mobility/plugins/fallthrough_accessors.rb +25 -25
- data/lib/mobility/plugins/locale_accessors.rb +22 -35
- data/lib/mobility/plugins/presence.rb +28 -21
- data/lib/mobility/plugins/query.rb +8 -17
- data/lib/mobility/plugins/reader.rb +50 -0
- data/lib/mobility/plugins/sequel.rb +34 -0
- data/lib/mobility/plugins/sequel/backend.rb +25 -0
- data/lib/mobility/plugins/sequel/cache.rb +24 -0
- data/lib/mobility/plugins/sequel/dirty.rb +33 -22
- data/lib/mobility/plugins/sequel/query.rb +21 -6
- data/lib/mobility/plugins/writer.rb +44 -0
- data/lib/mobility/translations.rb +95 -0
- data/lib/mobility/version.rb +12 -1
- data/lib/rails/generators/mobility/templates/initializer.rb +96 -78
- metadata +28 -27
- metadata.gz.sig +0 -0
- data/lib/mobility/active_model.rb +0 -4
- data/lib/mobility/active_model/backend_resetter.rb +0 -26
- data/lib/mobility/active_record.rb +0 -23
- data/lib/mobility/active_record/backend_resetter.rb +0 -26
- data/lib/mobility/active_record/uniqueness_validator.rb +0 -60
- data/lib/mobility/attributes.rb +0 -324
- data/lib/mobility/backend/orm_delegator.rb +0 -44
- data/lib/mobility/backend_resetter.rb +0 -50
- data/lib/mobility/configuration.rb +0 -138
- data/lib/mobility/fallbacks.rb +0 -28
- data/lib/mobility/interface.rb +0 -0
- data/lib/mobility/loaded.rb +0 -4
- data/lib/mobility/plugins/active_record/attribute_methods.rb +0 -38
- data/lib/mobility/plugins/cache/translation_cacher.rb +0 -40
- data/lib/mobility/sequel.rb +0 -9
- data/lib/mobility/sequel/backend_resetter.rb +0 -23
- data/lib/mobility/translates.rb +0 -73
|
@@ -13,47 +13,30 @@ If no locales are passed as an option to the initializer,
|
|
|
13
13
|
+Mobility.available_locales+ (i.e. +I18n.available_locales+, or Rails-set
|
|
14
14
|
available locales for a Rails application) will be used by default.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"title in #{Mobility.locale}"
|
|
20
|
-
end
|
|
21
|
-
include Mobility::Plugins::LocaleAccessors.new("title", locales: [:en, :fr])
|
|
22
|
-
end
|
|
16
|
+
=end
|
|
17
|
+
module LocaleAccessors
|
|
18
|
+
extend Plugin
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
post = Post.new
|
|
26
|
-
post.title
|
|
27
|
-
#=> "title in en"
|
|
28
|
-
post.title_fr
|
|
29
|
-
#=> "title in fr"
|
|
20
|
+
default true
|
|
30
21
|
|
|
31
|
-
=end
|
|
32
|
-
class LocaleAccessors < Module
|
|
33
22
|
# Apply locale accessors plugin to attributes.
|
|
34
|
-
# @param [
|
|
23
|
+
# @param [Translations] translations
|
|
35
24
|
# @param [Boolean] option
|
|
36
|
-
|
|
37
|
-
if
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# @param [Array<Symbol>] Locales
|
|
45
|
-
def initialize(*attribute_names, locales:)
|
|
46
|
-
attribute_names.each do |name|
|
|
47
|
-
locales.each do |locale|
|
|
48
|
-
define_reader(name, locale)
|
|
49
|
-
define_writer(name, locale)
|
|
25
|
+
initialize_hook do |*names|
|
|
26
|
+
if locales = options[:locale_accessors]
|
|
27
|
+
locales = Mobility.available_locales if locales == true
|
|
28
|
+
names.each do |name|
|
|
29
|
+
locales.each do |locale|
|
|
30
|
+
define_locale_reader(name, locale)
|
|
31
|
+
define_locale_writer(name, locale)
|
|
32
|
+
end
|
|
50
33
|
end
|
|
51
34
|
end
|
|
52
35
|
end
|
|
53
36
|
|
|
54
37
|
private
|
|
55
38
|
|
|
56
|
-
def
|
|
39
|
+
def define_locale_reader(name, locale)
|
|
57
40
|
warning_message = "locale passed as option to locale accessor will be ignored"
|
|
58
41
|
normalized_locale = Mobility.normalize_locale(locale)
|
|
59
42
|
|
|
@@ -61,18 +44,20 @@ available locales for a Rails application) will be used by default.
|
|
|
61
44
|
def #{name}_#{normalized_locale}(options = {})
|
|
62
45
|
return super() if options.delete(:super)
|
|
63
46
|
warn "#{warning_message}" if options[:locale]
|
|
64
|
-
#{name}(**options, locale:
|
|
47
|
+
#{name}(**options, locale: #{locale.inspect})
|
|
65
48
|
end
|
|
49
|
+
EOM
|
|
66
50
|
|
|
51
|
+
module_eval <<-EOM, __FILE__, __LINE__ + 1
|
|
67
52
|
def #{name}_#{normalized_locale}?(options = {})
|
|
68
53
|
return super() if options.delete(:super)
|
|
69
54
|
warn "#{warning_message}" if options[:locale]
|
|
70
|
-
#{name}?(**options, locale:
|
|
55
|
+
#{name}?(**options, locale: #{locale.inspect})
|
|
71
56
|
end
|
|
72
57
|
EOM
|
|
73
58
|
end
|
|
74
59
|
|
|
75
|
-
def
|
|
60
|
+
def define_locale_writer(name, locale)
|
|
76
61
|
warning_message = "locale passed as option to locale accessor will be ignored"
|
|
77
62
|
normalized_locale = Mobility.normalize_locale(locale)
|
|
78
63
|
|
|
@@ -80,10 +65,12 @@ available locales for a Rails application) will be used by default.
|
|
|
80
65
|
def #{name}_#{normalized_locale}=(value, options = {})
|
|
81
66
|
return super(value) if options.delete(:super)
|
|
82
67
|
warn "#{warning_message}" if options[:locale]
|
|
83
|
-
public_send(:#{name}=, value, **options, locale:
|
|
68
|
+
public_send(:#{name}=, value, **options, locale: #{locale.inspect})
|
|
84
69
|
end
|
|
85
70
|
EOM
|
|
86
71
|
end
|
|
87
72
|
end
|
|
73
|
+
|
|
74
|
+
register_plugin(:locale_accessors, LocaleAccessors)
|
|
88
75
|
end
|
|
89
76
|
end
|
|
@@ -6,43 +6,50 @@ module Mobility
|
|
|
6
6
|
=begin
|
|
7
7
|
|
|
8
8
|
Applies presence filter to values fetched from backend and to values set on
|
|
9
|
-
backend.
|
|
9
|
+
backend.
|
|
10
10
|
|
|
11
11
|
@note For performance reasons, the presence plugin filters only for empty
|
|
12
12
|
strings, not other values continued "blank" like empty arrays.
|
|
13
13
|
|
|
14
14
|
=end
|
|
15
15
|
module Presence
|
|
16
|
+
extend Plugin
|
|
17
|
+
|
|
18
|
+
default true
|
|
19
|
+
requires :backend, include: :before
|
|
20
|
+
|
|
16
21
|
# Applies presence plugin to attributes.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def self.apply(attributes, option)
|
|
20
|
-
attributes.backend_class.include(self) if option
|
|
22
|
+
included_hook do |_, backend_class|
|
|
23
|
+
backend_class.include(BackendMethods) if options[:presence]
|
|
21
24
|
end
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
options
|
|
29
|
-
|
|
26
|
+
module BackendMethods
|
|
27
|
+
# @!group Backend Accessors
|
|
28
|
+
# @!macro backend_reader
|
|
29
|
+
# @option options [Boolean] presence
|
|
30
|
+
# *false* to disable presence filter.
|
|
31
|
+
def read(locale, **options)
|
|
32
|
+
options.delete(:presence) == false ? super : Presence[super]
|
|
33
|
+
end
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
# @!macro backend_writer
|
|
36
|
+
# @option options [Boolean] presence
|
|
37
|
+
# *false* to disable presence filter.
|
|
38
|
+
def write(locale, value, **options)
|
|
39
|
+
if options.delete(:presence) == false
|
|
40
|
+
super
|
|
41
|
+
else
|
|
42
|
+
super(locale, Presence[value], **options)
|
|
43
|
+
end
|
|
39
44
|
end
|
|
45
|
+
# @!endgroup
|
|
40
46
|
end
|
|
41
|
-
# @!endgroup
|
|
42
47
|
|
|
43
48
|
def self.[](value)
|
|
44
49
|
(value == "") ? nil : value
|
|
45
50
|
end
|
|
46
51
|
end
|
|
52
|
+
|
|
53
|
+
register_plugin(:presence, Presence)
|
|
47
54
|
end
|
|
48
55
|
end
|
|
@@ -3,29 +3,20 @@ module Mobility
|
|
|
3
3
|
module Plugins
|
|
4
4
|
=begin
|
|
5
5
|
|
|
6
|
-
@see {Mobility::Plugins::ActiveRecord::Query}
|
|
6
|
+
@see {Mobility::Plugins::ActiveRecord::Query} or {Mobility::Plugins::Sequel::Query}.
|
|
7
7
|
|
|
8
8
|
=end
|
|
9
9
|
module Query
|
|
10
|
-
|
|
11
|
-
def apply(attributes, option)
|
|
12
|
-
if option
|
|
13
|
-
include_query_module(attributes)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
10
|
+
extend Plugin
|
|
16
11
|
|
|
17
|
-
|
|
12
|
+
default :i18n
|
|
13
|
+
requires :backend, include: :before
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
require "mobility/plugins/active_record/query"
|
|
22
|
-
ActiveRecord::Query.apply(attributes)
|
|
23
|
-
elsif Loaded::Sequel && attributes.model_class < ::Sequel::Model
|
|
24
|
-
require "mobility/plugins/sequel/query"
|
|
25
|
-
Sequel::Query.apply(attributes)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
15
|
+
def query_method
|
|
16
|
+
(options[:query] == true) ? self.class.defaults[:query] : options[:query]
|
|
28
17
|
end
|
|
29
18
|
end
|
|
19
|
+
|
|
20
|
+
register_plugin(:query, Query)
|
|
30
21
|
end
|
|
31
22
|
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Mobility
|
|
4
|
+
module Plugins
|
|
5
|
+
module Reader
|
|
6
|
+
=begin
|
|
7
|
+
|
|
8
|
+
Defines attribute reader that delegates to +Mobility::Backend#read+.
|
|
9
|
+
|
|
10
|
+
=end
|
|
11
|
+
extend Plugin
|
|
12
|
+
|
|
13
|
+
default true
|
|
14
|
+
requires :backend
|
|
15
|
+
|
|
16
|
+
initialize_hook do |*names, **|
|
|
17
|
+
if options[:reader]
|
|
18
|
+
names.each do |name|
|
|
19
|
+
class_eval <<-EOM, __FILE__, __LINE__ + 1
|
|
20
|
+
def #{name}(locale: nil, **options)
|
|
21
|
+
#{Reader.setup_source}
|
|
22
|
+
mobility_backends[:#{name}].read(locale, **options)
|
|
23
|
+
end
|
|
24
|
+
EOM
|
|
25
|
+
class_eval <<-EOM, __FILE__, __LINE__ + 1
|
|
26
|
+
def #{name}?(locale: nil, **options)
|
|
27
|
+
#{Reader.setup_source}
|
|
28
|
+
mobility_backends[:#{name}].present?(locale, **options)
|
|
29
|
+
end
|
|
30
|
+
EOM
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.setup_source
|
|
36
|
+
<<-EOL
|
|
37
|
+
return super() if options[:super]
|
|
38
|
+
if (locale &&= locale.to_sym)
|
|
39
|
+
#{"Mobility.enforce_available_locales!(locale)" if I18n.enforce_available_locales}
|
|
40
|
+
options[:locale] = true
|
|
41
|
+
else
|
|
42
|
+
locale = Mobility.locale
|
|
43
|
+
end
|
|
44
|
+
EOL
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
register_plugin(:reader, Reader)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -1,6 +1,40 @@
|
|
|
1
|
+
require "sequel"
|
|
2
|
+
raise VersionNotSupportedError, "Mobility is only compatible with Sequel 4.0 and greater" if ::Sequel::MAJOR < 4
|
|
3
|
+
require "sequel/plugins/mobility"
|
|
4
|
+
unless defined?(ActiveSupport::Inflector)
|
|
5
|
+
# TODO: avoid automatically including the inflector extension
|
|
6
|
+
require "sequel/extensions/inflector"
|
|
7
|
+
end
|
|
8
|
+
require "sequel/plugins/dirty"
|
|
9
|
+
require_relative "./sequel/backend"
|
|
10
|
+
require_relative "./sequel/dirty"
|
|
11
|
+
require_relative "./sequel/cache"
|
|
12
|
+
require_relative "./sequel/query"
|
|
13
|
+
|
|
1
14
|
module Mobility
|
|
2
15
|
module Plugins
|
|
3
16
|
module Sequel
|
|
17
|
+
extend Plugin
|
|
18
|
+
|
|
19
|
+
requires :sequel_backend, include: :after
|
|
20
|
+
requires :sequel_dirty
|
|
21
|
+
requires :sequel_cache
|
|
22
|
+
requires :sequel_query
|
|
23
|
+
|
|
24
|
+
included_hook do |klass|
|
|
25
|
+
unless sequel_class?(klass)
|
|
26
|
+
name = klass.name || klass.to_s
|
|
27
|
+
raise TypeError, "#{name} should be a subclass of Sequel::Model to use the sequel plugin"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def sequel_class?(klass)
|
|
34
|
+
klass < ::Sequel::Model
|
|
35
|
+
end
|
|
4
36
|
end
|
|
37
|
+
|
|
38
|
+
register_plugin(:sequel, Sequel)
|
|
5
39
|
end
|
|
6
40
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Mobility
|
|
2
|
+
module Plugins
|
|
3
|
+
module Sequel
|
|
4
|
+
module Backend
|
|
5
|
+
extend Plugin
|
|
6
|
+
|
|
7
|
+
requires :backend, include: :before
|
|
8
|
+
|
|
9
|
+
def load_backend(backend)
|
|
10
|
+
if Symbol === backend
|
|
11
|
+
require "mobility/backends/sequel/#{backend}"
|
|
12
|
+
Backends.load_backend("sequel_#{backend}".to_sym)
|
|
13
|
+
else
|
|
14
|
+
super
|
|
15
|
+
end
|
|
16
|
+
rescue LoadError => e
|
|
17
|
+
raise unless e.message =~ /sequel\/#{backend}/
|
|
18
|
+
super
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
register_plugin(:sequel_backend, Sequel::Backend)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Mobility
|
|
4
|
+
module Plugins
|
|
5
|
+
module Sequel
|
|
6
|
+
=begin
|
|
7
|
+
|
|
8
|
+
Adds hook to clear Mobility cache when +refresh+ is called on Sequel model.
|
|
9
|
+
|
|
10
|
+
=end
|
|
11
|
+
module Cache
|
|
12
|
+
extend Plugin
|
|
13
|
+
|
|
14
|
+
requires :cache, include: false
|
|
15
|
+
|
|
16
|
+
included_hook do |klass|
|
|
17
|
+
define_cache_hooks(klass, :refresh) if options[:cache]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
register_plugin(:sequel_cache, Sequel::Cache)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -13,29 +13,37 @@ Automatically includes dirty plugin in model class when enabled.
|
|
|
13
13
|
=end
|
|
14
14
|
module Sequel
|
|
15
15
|
module Dirty
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def initialize(*attribute_names)
|
|
20
|
-
# Although we load the plugin in the included callback method, we
|
|
21
|
-
# need to include this module here in advance to ensure that its
|
|
22
|
-
# instance methods are included *before* the ones defined here.
|
|
23
|
-
include ::Sequel::Plugins::Dirty::InstanceMethods
|
|
24
|
-
|
|
25
|
-
%w[initial_value column_change column_changed? reset_column].each do |method_name|
|
|
26
|
-
define_method method_name do |column|
|
|
27
|
-
if attribute_names.map(&:to_sym).include?(column)
|
|
28
|
-
super(Mobility.normalize_locale_accessor(column).to_sym)
|
|
29
|
-
else
|
|
30
|
-
super(column)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
16
|
+
extend Plugin
|
|
17
|
+
|
|
18
|
+
requires :dirty, include: false
|
|
35
19
|
|
|
36
|
-
|
|
20
|
+
initialize_hook do
|
|
21
|
+
# Although we load the plugin in the included callback method, we
|
|
22
|
+
# need to include this module here in advance to ensure that its
|
|
23
|
+
# instance methods are included *before* the ones defined here.
|
|
24
|
+
include ::Sequel::Plugins::Dirty::InstanceMethods
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
included_hook do |klass, backend_class|
|
|
28
|
+
if options[:dirty]
|
|
37
29
|
# this just adds Sequel::Plugins::Dirty to @plugins
|
|
38
|
-
|
|
30
|
+
klass.plugin :dirty
|
|
31
|
+
define_dirty_methods(names)
|
|
32
|
+
backend_class.include BackendMethods
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def define_dirty_methods(names)
|
|
39
|
+
%w[initial_value column_change column_changed? reset_column].each do |method_name|
|
|
40
|
+
define_method method_name do |column|
|
|
41
|
+
if names.map(&:to_sym).include?(column)
|
|
42
|
+
super(Mobility.normalize_locale_accessor(column).to_sym)
|
|
43
|
+
else
|
|
44
|
+
super(column)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
39
47
|
end
|
|
40
48
|
end
|
|
41
49
|
|
|
@@ -48,14 +56,17 @@ Automatically includes dirty plugin in model class when enabled.
|
|
|
48
56
|
if model.column_changes.has_key?(locale_accessor) && model.initial_values[locale_accessor] == value
|
|
49
57
|
super
|
|
50
58
|
[model.changed_columns, model.initial_values].each { |h| h.delete(locale_accessor) }
|
|
51
|
-
elsif read(locale, options.merge(fallback: false)) != value
|
|
59
|
+
elsif read(locale, **options.merge(fallback: false)) != value
|
|
52
60
|
model.will_change_column(locale_accessor)
|
|
53
61
|
super
|
|
54
62
|
end
|
|
55
63
|
end
|
|
56
64
|
# @!endgroup
|
|
57
65
|
end
|
|
66
|
+
|
|
58
67
|
end
|
|
59
68
|
end
|
|
69
|
+
|
|
70
|
+
register_plugin(:sequel_dirty, Sequel::Dirty)
|
|
60
71
|
end
|
|
61
72
|
end
|
|
@@ -8,11 +8,18 @@ See ActiveRecord::Query plugin.
|
|
|
8
8
|
=end
|
|
9
9
|
module Sequel
|
|
10
10
|
module Query
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
extend Plugin
|
|
12
|
+
|
|
13
|
+
requires :query, include: false
|
|
14
|
+
|
|
15
|
+
included_hook do |klass, _|
|
|
16
|
+
plugin = self
|
|
17
|
+
if options[:query]
|
|
18
|
+
raise MissingBackend, "backend required for Query plugin" unless backend_class
|
|
19
|
+
|
|
20
|
+
klass.class_eval do
|
|
14
21
|
extend QueryMethod
|
|
15
|
-
singleton_class.send :alias_method,
|
|
22
|
+
singleton_class.send :alias_method, plugin.query_method, :__mobility_query_dataset__
|
|
16
23
|
end
|
|
17
24
|
end
|
|
18
25
|
end
|
|
@@ -95,7 +102,7 @@ See ActiveRecord::Query plugin.
|
|
|
95
102
|
|
|
96
103
|
class << self
|
|
97
104
|
def build(dataset, query_method, query_conds, &block)
|
|
98
|
-
return yield unless Hash === query_conds.first
|
|
105
|
+
return yield unless ::Hash === query_conds.first
|
|
99
106
|
|
|
100
107
|
cond = query_conds.first.dup
|
|
101
108
|
locale = cond.delete(:locale) || Mobility.locale
|
|
@@ -109,7 +116,7 @@ See ActiveRecord::Query plugin.
|
|
|
109
116
|
keys, predicates = cond.keys, []
|
|
110
117
|
model = dataset.model
|
|
111
118
|
|
|
112
|
-
query_map = model.
|
|
119
|
+
query_map = attribute_modules(model).inject(IDENTITY) do |qm, mod|
|
|
113
120
|
i18n_keys = mod.names.map(&:to_sym) & keys
|
|
114
121
|
next qm if i18n_keys.empty?
|
|
115
122
|
|
|
@@ -127,6 +134,10 @@ See ActiveRecord::Query plugin.
|
|
|
127
134
|
query_map[dataset.public_send(query_method, ::Sequel.&(*predicates))]
|
|
128
135
|
end
|
|
129
136
|
|
|
137
|
+
def attribute_modules(model)
|
|
138
|
+
model.ancestors.grep(::Mobility::Translations)
|
|
139
|
+
end
|
|
140
|
+
|
|
130
141
|
def build_predicate(op, values)
|
|
131
142
|
vals = values.is_a?(Array) ? values.uniq: [values]
|
|
132
143
|
vals = vals.first if vals.size == 1
|
|
@@ -135,6 +146,10 @@ See ActiveRecord::Query plugin.
|
|
|
135
146
|
end
|
|
136
147
|
end
|
|
137
148
|
end
|
|
149
|
+
|
|
150
|
+
class MissingBackend < Mobility::Error; end
|
|
138
151
|
end
|
|
152
|
+
|
|
153
|
+
register_plugin(:sequel_query, Sequel::Query)
|
|
139
154
|
end
|
|
140
155
|
end
|