lib/mobility/plugins/sequel/query.rb in mobility-1.0.7 vs lib/mobility/plugins/sequel/query.rb in mobility-1.1.0
- old
+ new
@@ -1,11 +1,12 @@
# frozen-string-literal: true
module Mobility
module Plugins
=begin
-See ActiveRecord::Query plugin.
+Supports querying on Sequel model translated attributes. Similar API to the
+ActiveRecord query plugin.
=end
module Sequel
module Query
extend Plugin
@@ -17,62 +18,80 @@
if options[:query]
raise MissingBackend, "backend required for Query plugin" unless backend_class
klass.class_eval do
extend QueryMethod
- singleton_class.send :alias_method, plugin.query_method, :__mobility_query_dataset__
+ singleton_class.define_method(plugin.query_method) do |locale: Mobility.locale, &block|
+ Query.build_query(self, locale, &block)
+ end
end
end
end
- module QueryMethod
- def __mobility_query_dataset__(locale: Mobility.locale, &block)
+ class << self
+ def build_query(klass, locale = Mobility.locale, &block)
if block_given?
- VirtualRow.build_query(self, locale, &block)
+ VirtualRow.build_query(klass, locale, &block)
else
- dataset.with_extend(QueryExtension)
+ klass.dataset.with_extend(QueryExtension)
end
end
end
+ module QueryMethod
+ def __mobility_query_dataset__(locale: Mobility.locale, &block)
+ warn '__mobility_query_dataset__ is an internal method and will be deprecated in the next release.'
+ Query.build_query(self, locale, &block)
+ end
+ end
+
# Internal class to create a "clean room" for manipulating translated
# attribute nodes in an instance-eval'ed block. Inspired by Sequel's
# (much more sophisticated) virtual rows.
class VirtualRow < BasicObject
- attr_reader :__backends
+ attr_reader :backends, :locales
- def initialize(model_class, locale)
- @model_class, @locale, @__backends = model_class, locale, []
+ def initialize(model_class, global_locale)
+ @model_class, @global_locale, @backends, @locales = model_class, global_locale, [], []
end
- def method_missing(m, *)
+ def method_missing(m, *args)
if @model_class.mobility_attribute?(m)
- @__backends |= [@model_class.mobility_backend_class(m)]
- @model_class.mobility_backend_class(m).build_op(m.to_s, @locale)
+ @backends |= [@model_class.mobility_backend_class(m)]
+ ::Mobility.validate_locale!(args[0]) if args[0]
+ locale = args[0] || @global_locale
+ @locales |= [locale]
+ @model_class.mobility_backend_class(m).build_op(m.to_s, locale)
elsif @model_class.columns.include?(m.to_s)
::Sequel::SQL::QualifiedIdentifier.new(@model_class.table_name, m)
else
super
end
end
class << self
def build_query(klass, locale, &block)
+ ::Mobility.validate_locale!(locale)
+
row = new(klass, locale)
query = block.arity.zero? ? row.instance_eval(&block) : block.call(row)
if ::Sequel::Dataset === query
predicates = query.opts[:where]
- prepare_datasets(query, row.__backends, locale, predicates)
+ prepare_datasets(query, row.backends, row.locales, predicates)
else
- prepare_datasets(klass.dataset, row.__backends, locale, query).where(query)
+ prepare_datasets(klass.dataset, row.backends, row.locales, query).where(query)
end
end
private
- def prepare_datasets(dataset, backends, locale, predicates)
- backends.inject(dataset) { |ds, b| b.prepare_dataset(ds, predicates, locale) }
+ def prepare_datasets(dataset, backends, locales, predicates)
+ backends.inject(dataset) do |dataset_, b|
+ locales.inject(dataset_) do |ds, locale|
+ b.prepare_dataset(ds, predicates, locale)
+ end
+ end
end
end
end
private_constant :QueryMethod, :VirtualRow