Module: Protobuf::Mongoid::Scope::ClassMethods
- Defined in:
- lib/protobuf/mongoid/scope.rb
Overview
Class Methods
Instance Method Summary collapse
-
#field_scope(field, options = {}) ⇒ Object
Define fields that should be searchable via ‘search_scope`.
- #for_upsert(proto) ⇒ Object
-
#model_scope ⇒ Object
:noapi:.
-
#parse_search_values(proto, field) ⇒ Object
:noapi:.
-
#search_scope(proto) ⇒ Object
Builds and returns a Arel relation based on the fields that are present in the given protobuf message using the searchable fields to determine what scopes to use.
-
#searchable_field_parsers ⇒ Object
:noapi:.
-
#searchable_fields ⇒ Object
:noapi:.
- #upsert(proto) ⇒ Object
- #upsert!(proto) ⇒ Object
-
#upsert_key(*fields) ⇒ Object
Defines a scope that is eligible for upsert.
- #upsert_keys ⇒ Object
Instance Method Details
#field_scope(field, options = {}) ⇒ Object
Define fields that should be searchable via ‘search_scope`. Accepts a protobuf field and an already defined scope. If no scope is specified, the scope will be the field name, prefixed with `by_` (e.g. when the field is :guid, the scope will be :by_guid).
Optionally, a parser can be provided that will be called, passing the field value as an argument. This allows custom data parsers to be used so that they don’t have to be handled by scopes. Parsers can be procs, lambdas, or symbolized method names and must accept the value of the field as a parameter.
Examples:
class User
include Mongoid::Base
scope :by_guid, lambda { |*guids| where(:guid => guids) }
scope :custom_guid_scope, lambda { |*guids| where(:guid => guids) }
# Equivalent to `field_scope :guid, :by_guid`
field_scope :guid
# With a custom scope
field_scope :guid, :scope => :custom_guid_scope
# With a custom parser that converts the value to an integer
field_scope :guid, :scope => :custom_guid_scope, :parser => lambda { |value| value.to_i }
end
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/protobuf/mongoid/scope.rb', line 51 def field_scope(field, = {}) scope_name = if .include?(:scope) [:scope] else # When no scope is defined, assume the scope is the field, prefixed with `by_` :"by_#{field}" end searchable_fields[field] = scope_name searchable_field_parsers[field] = [:parser] if [:parser] end |
#for_upsert(proto) ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/protobuf/mongoid/scope.rb', line 168 def for_upsert(proto) valid_upsert = upsert_keys.find do |upsert_key| upsert_key.all? do |field| proto.respond_to_and_has_and_present?(field) end end fail UpsertNotFoundError unless valid_upsert.present? upsert_scope = model_scope valid_upsert.each do |field| value = proto.__send__(field) upsert_scope = upsert_scope.__send__(searchable_fields[field], value) end upsert_scope.first_or_initialize end |
#model_scope ⇒ Object
:noapi:
64 65 66 |
# File 'lib/protobuf/mongoid/scope.rb', line 64 def model_scope all end |
#parse_search_values(proto, field) ⇒ Object
:noapi:
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/protobuf/mongoid/scope.rb', line 69 def parse_search_values(proto, field) value = proto.__send__(field) if searchable_field_parsers[field] parser = searchable_field_parsers[field] if parser.respond_to?(:to_sym) value = self.__send__(parser.to_sym, value) else value = parser.call(value) end end values = [value].flatten values.map!(&:to_i) if proto.class.get_field(field, true).enum? values end |
#search_scope(proto) ⇒ Object
Builds and returns a Arel relation based on the fields that are present in the given protobuf message using the searchable fields to determine what scopes to use. Provides several aliases for variety.
Examples:
# Search starting with the default scope and searchable fields
User.search_scope(request)
User.by_fields(request)
User.scope_from_proto(request)
98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/protobuf/mongoid/scope.rb', line 98 def search_scope(proto) search_relation = model_scope searchable_fields.each do |field, scope_name| next unless proto.respond_to_and_has_and_present?(field) search_values = parse_search_values(proto, field) search_relation = search_relation.__send__(scope_name, *search_values) search_relation.selector[field] = { "$in" => search_values } if search_values.class == Array end search_relation end |
#searchable_field_parsers ⇒ Object
:noapi:
118 119 120 |
# File 'lib/protobuf/mongoid/scope.rb', line 118 def searchable_field_parsers @_searchable_field_parsers ||= {} end |
#searchable_fields ⇒ Object
:noapi:
113 114 115 |
# File 'lib/protobuf/mongoid/scope.rb', line 113 def searchable_fields @_searchable_fields ||= {} end |
#upsert(proto) ⇒ Object
186 187 188 189 190 191 |
# File 'lib/protobuf/mongoid/scope.rb', line 186 def upsert(proto) document = for_upsert(proto) document.assign_attributes(proto) document.save document end |
#upsert!(proto) ⇒ Object
193 194 195 196 197 198 |
# File 'lib/protobuf/mongoid/scope.rb', line 193 def upsert!(proto) document = for_upsert(proto) document.assign_attributes(proto) document.save! document end |
#upsert_key(*fields) ⇒ Object
Defines a scope that is eligible for upsert. The scope will be used to initialize a document with first_or_initialize. An upsert scope declariation must specify one or more fields that are required to be present on the request and also must have a field_scope defined.
If multiple upsert scopes are specified, they will be searched in the order they are declared for the first valid scope.
Examples:
class User
include Mongoid::Base
scope :by_guid, lambda { |*guids| where(:guid => guids) }
scope :by_external_guid, lambda { |*external_guids|
where(:external_guid => exteranl_guids)
}
scope :by_client_guid, lambda { |*client_guids|
joins(:client).where(
:clients => { :guid => client_guids }
)
}
field_scope :guid
field_scope :client_guid
field_scope :external_guid
upsert_scope :external_guid, :client_guid
upsert_scope :guid
end
154 155 156 157 158 159 160 161 162 |
# File 'lib/protobuf/mongoid/scope.rb', line 154 def upsert_key(*fields) fields = fields.flatten fields.each do |field| fail UpsertScopeError unless searchable_fields[field].present? end upsert_keys << fields end |
#upsert_keys ⇒ Object
164 165 166 |
# File 'lib/protobuf/mongoid/scope.rb', line 164 def upsert_keys @_upsert_keys ||= [] end |