Class: Parse::Constraint::DoesNotEqualLinkedPointerConstraint
- Inherits:
-
Constraint
- Object
- Constraint
- Parse::Constraint::DoesNotEqualLinkedPointerConstraint
- Defined in:
- lib/parse/query/constraints.rb
Overview
Constraint for comparing pointer fields where they do NOT equal through linked objects. Uses MongoDB's $lookup to join collections and $expr with $ne to compare fields.
Usage:
Document.where(:project.does_not_equal_linked_pointer => { through: :post, field: :project })
This generates a MongoDB aggregation pipeline that:
- Uses $lookup to join the linked collection
- Uses $match with $expr and $ne to find records where fields do NOT match
Instance Method Summary collapse
-
#build ⇒ Hash
Builds the MongoDB aggregation pipeline for the does-not-equal-linked-pointer constraint.
Instance Method Details
#build ⇒ Hash
Builds the MongoDB aggregation pipeline for the does-not-equal-linked-pointer constraint
3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 |
# File 'lib/parse/query/constraints.rb', line 3162 def build # Validate that value is a hash with required keys unless @value.is_a?(Hash) && @value[:through] && @value[:field] raise ArgumentError, "DoesNotEqualLinkedPointerConstraint requires a hash with :through and :field keys" end through_field = @value[:through] target_field = @value[:field] # Convert field names to Parse format (snake_case to camelCase) with _p_ prefix for pointers local_field_name = format_field_name(@operation.operand, is_pointer: true) through_field_name = format_field_name(through_field, is_pointer: true) target_field_name = format_field_name(target_field, is_pointer: true) # Determine the collection name for the lookup (Rails pluralization) through_class_name = through_field.to_s.classify lookup_collection = through_class_name # Generate unique alias name for the joined data (use clean name without _p_ prefix) lookup_alias = "#{through_field.to_s.camelize(:lower)}_data" # Build the MongoDB aggregation pipeline pipeline = [] # Parse stores pointers as "ClassName$objectId" strings # We need to extract just the objectId part after the $ # Stage 1: Add field with extracted objectId add_fields_stage = { "$addFields" => { "#{through_field_name}_id" => { "$substr" => [ "$#{through_field_name}", lookup_collection.length + 1, # Skip "ClassName$" -1, # Rest of string ], }, }, } pipeline << add_fields_stage # Stage 2: $lookup to join the linked collection lookup_stage = { "$lookup" => { "from" => lookup_collection, "localField" => through_field_name, "foreignField" => "_id", "as" => lookup_alias, }, } pipeline << lookup_stage # Stage 2: $match with $expr to compare the fields using $ne (not equal) match_stage = { "$match" => { "$expr" => { "$ne" => [ { "$arrayElemAt" => ["$#{lookup_alias}.#{target_field_name}", 0] }, "$#{local_field_name}", ], }, }, } pipeline << match_stage # Return a special marker that indicates this needs aggregation pipeline processing { "__aggregation_pipeline" => pipeline } end |