Skip to content

Commit 1650cf9

Browse files
committed
feat: Add direct connections endpoint to airports controller
1 parent 470c169 commit 1650cf9

File tree

4 files changed

+55
-26
lines changed

4 files changed

+55
-26
lines changed

app/controllers/api/v1/airports_controller.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,25 @@ def index
108108
end
109109
end
110110

111+
# GET /api/v1/airports/direct-connections
112+
def direct_connections
113+
raise ArgumentError, 'Source airport is missing' unless params[:sourceAirportCode].present?
114+
115+
source_airport = params[:sourceAirportCode]
116+
limit = params[:limit] || 10
117+
offset = params[:offset] || 0
118+
119+
begin
120+
destination_airports = Route.direct_connections(key: [source_airport, limit, offset])
121+
.pluck(:destinationairport)
122+
render json: destination_airports, status: :ok
123+
rescue ArgumentError => e
124+
render json: { error: 'Invalid request', message: e.message }, status: :bad_request
125+
rescue StandardError => e
126+
render json: { error: 'Internal server error', message: e.message }, status: :internal_server_error
127+
end
128+
end
129+
111130
private
112131

113132
def set_airport

app/models/airport.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
require 'couchbase-orm'
4+
5+
# GeoCoordinates nested document
16
class GeoCoordinates < CouchbaseOrm::NestedDocument
27
attribute :lat, :float
38
attribute :lon, :float
@@ -8,6 +13,7 @@ class GeoCoordinates < CouchbaseOrm::NestedDocument
813
validates :alt, presence: true, numericality: { greater_than_or_equal_to: -1000, less_than_or_equal_to: 10_000 }
914
end
1015

16+
# Airport model
1117
class Airport < CouchbaseOrm::Base
1218
attribute :airportname, :string
1319
attribute :city, :string

app/models/route.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,8 @@ class Route < CouchbaseOrm::Base
2626
validates :equipment, presence: true
2727
validates :schedule, presence: true
2828
validates :distance, presence: true, numericality: { greater_than_or_equal_to: 0 }
29+
30+
n1ql :direct_connections, query_fn: proc { |bucket, values, options|
31+
cluster.query("SELECT distinct raw meta(route).id FROM `#{bucket.name}` AS airport JOIN `#{bucket.name}` AS route ON route.sourceairport = airport.faa WHERE airport.faa = #{quote(values[0])} AND route.stops = 0 LIMIT #{values[1]} OFFSET #{values[2]}", options)
32+
}
2933
end

test/integration/airports_spec.rb

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -191,30 +191,30 @@
191191
end
192192
end
193193

194-
# describe 'GET /api/v1/airports/direct-connections' do
195-
# let(:destination_airport_code) { 'JFK' }
196-
# let(:limit) { 10 }
197-
# let(:offset) { 0 }
198-
# let(:expected_connections) { %w[DEL LHR EZE ATL CUN MEX LAX SAN SEA SFO] }
199-
200-
# context 'when the destination airport code is provided' do
201-
# it 'returns the direct connections' do
202-
# get '/api/v1/airports/direct-connections',
203-
# params: { destinationAirportCode: destination_airport_code, limit: limit, offset: offset }
204-
205-
# expect(response).to have_http_status(:ok)
206-
# expect(response.content_type).to eq('application/json; charset=utf-8')
207-
# expect(JSON.parse(response.body)).to eq(expected_connections)
208-
# end
209-
# end
210-
211-
# context 'when the destination airport code is not provided' do
212-
# it 'returns a bad request error' do
213-
# get '/api/v1/airports/direct-connections'
214-
215-
# expect(response).to have_http_status(:bad_request)
216-
# expect(JSON.parse(response.body)).to eq({ 'message' => 'Destination airport code is required' })
217-
# end
218-
# end
219-
# end
194+
describe 'GET /api/v1/airports/direct-connections' do
195+
let(:destination_airport_code) { 'JFK' }
196+
let(:limit) { 10 }
197+
let(:offset) { 0 }
198+
let(:expected_connections) { %w[DEL LHR EZE ATL CUN MEX LAX SAN SEA SFO] }
199+
200+
context 'when the destination airport code is provided' do
201+
it 'returns the direct connections' do
202+
get '/api/v1/airports/direct-connections',
203+
params: { destinationAirportCode: destination_airport_code, limit:, offset: }
204+
205+
expect(response).to have_http_status(:ok)
206+
expect(response.content_type).to eq('application/json; charset=utf-8')
207+
expect(JSON.parse(response.body)).to eq(expected_connections)
208+
end
209+
end
210+
211+
context 'when the destination airport code is not provided' do
212+
it 'returns a bad request error' do
213+
get '/api/v1/airports/direct-connections'
214+
215+
expect(response).to have_http_status(:bad_request)
216+
expect(JSON.parse(response.body)).to eq({ 'message' => 'Destination airport code is required' })
217+
end
218+
end
219+
end
220220
end

0 commit comments

Comments
 (0)