Class: Parse::Constraint::DoesNotEqualLinkedPointerConstraint
- Inherits:
-
Parse::Constraint
- Object
- Parse::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 Attribute Summary
Attributes inherited from Parse::Constraint
#operand, #operation, #operator, #value
Instance Method Summary collapse
-
#build ⇒ Hash
Builds the MongoDB aggregation pipeline for the does-not-equal-linked-pointer constraint.
Methods inherited from Parse::Constraint
#as_json, constraint_keyword, create, formatted_value, #formatted_value, #initialize, #key, #precedence, #regex_unicode_option, register, #to_s
Constructor Details
This class inherits a constructor from Parse::Constraint
Instance Method Details
#build ⇒ Hash
Builds the MongoDB aggregation pipeline for the does-not-equal-linked-pointer constraint
3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 |
# File 'lib/parse/query/constraints.rb', line 3106 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 |