def find_events_by_coordinate(event)
return event if @coordinates.nil?
return event if @coordinates['latitude'].nil? || @coordinates['longitude'].nil?
if @coordinates['latitude'].is_a? String
@coordinates['latitude'] = @coordinates['latitude'].to_f
end
if @coordinates['longitude'].is_a? String
@coordinates['longitude'] = @coordinates['longitude'].to_f
end
return event if @coordinates['latitude'].nan? || @coordinates['longitude'].nan?
return event if @coordinates['latitude'] == 0.0 || @coordinates['latitude'] == 0.0
# Build query which defines a coordinate search based on search params
venues_query = Venue.select('venues.id')
.distance_to_point(
srid: @coordinates['srid'],
lat: @coordinates['latitude'],
lng: @coordinates['longitude'],
distance: @coordinates['proximity_threshold']
)
.where_distance_within(
coordinate: {
srid: @coordinates['srid'],
lat: @coordinates['latitude'],
lng: @coordinates['longitude']
},
distance: @coordinates['proximity_threshold']
)
.order('distance ASC')
# Build a CTE and use the coordinate search query's AST
# as the logic within it.
ordered_venues_cte = Arel::Table.new(:ordered_venues)
ordered_venues = Arel::Nodes::As.new(
ordered_venues_cte, venues_query.arel
)
# Build a CTE and use the event model joined with the coordinates search CTE
# via the events_venues table.
event_table = Event.arel_table
events_venues_table = Arel::Table.new(:events_venues, ActiveRecord::Base)
matching_events_cte = Arel::Table.new(:matching_events)
matching_events = Arel::Nodes::As.new(
matching_events_cte,
event_table.project(
'events.*',
ordered_venues_cte[:id].as('venue_id'),
ordered_venues_cte[:distance].as('distance')
)
.join(events_venues_table)
.on(events_venues_table[:event_id].eq(event_table[:id]))
.join(ordered_venues_cte)
.on(events_venues_table[:venue_id].eq(ordered_venues_cte[:id]))
)
# Query the resultant CTE, ordering the results by distance
events_query = Arel::Table.new('matching_events')
.project('matching_events.*')
.order('distance ASC')
.with(ordered_venues, matching_events)
@queries += 1
events_query
end