Skip to content

Commit d553058

Browse files
committed
add limit
1 parent c33f067 commit d553058

File tree

5 files changed

+120
-22
lines changed

5 files changed

+120
-22
lines changed

Readme.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,24 @@ _parámetros necesarios_
4848
```text
4949
codigo_postal=# codigo a buscar, parcial o total
5050
```
51+
52+
_parámetros opcionales_
53+
```text
54+
limit=# número máximo de resultados a devolver
55+
```
56+
5157
_Ejemplo de búsqueda para códigos que inicien con **66**, con **664** y con **6641**_
5258
```json
5359
https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=66
5460
https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=664
5561
https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=6641
5662
```
5763

64+
_Ejemplo de búsqueda limitada a 3 resultados_
65+
```json
66+
https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=66&limit=3
67+
```
68+
5869
** Para el código postal 6641 el servidor regresa **
5970
```json
6071
{
@@ -87,6 +98,7 @@ _parámetros necesarios_
8798
_parámetros opcionales_
8899
```text
89100
colonia=# nombre de la colonia (opcional)
101+
limit=# número máximo de resultados a devolver
90102
```
91103

92104
_Ejemplo de búsqueda para códigos postales en Nuevo León, San Nicolás de los Garza_
@@ -99,6 +111,11 @@ _Ejemplo de búsqueda para códigos postales en Nuevo León, San Nicolás de los
99111
https://mexico-zip-codes.p.rapidapi.com/v2/buscar_por_ubicacion?estado=Nuevo%20León&municipio=San%20Nicolás%20de%20los%20Garza&colonia=Praderas%20de%20Santo%20Domingo
100112
```
101113

114+
_Ejemplo de búsqueda limitada a 5 resultados_
115+
```text
116+
https://mexico-zip-codes.p.rapidapi.com/v2/buscar_por_ubicacion?estado=Nuevo%20León&municipio=San%20Nicolás%20de%20los%20Garza&limit=5
117+
```
118+
102119
**Respuesta del servidor**
103120
```json
104121
{

app.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@
3030
on 'v2/buscar', param('codigo_postal') do |codigo_postal|
3131
res.headers['Cache-Control'] = 'max-age=525600, public'
3232
res.headers['Access-Control-Allow-Origin'] = '*'
33-
res.write PostalCodes.fetch_codes(codigo_postal)
33+
limit = req.params['limit']&.to_i
34+
res.write PostalCodes.fetch_codes(codigo_postal, limit)
3435
end
3536

3637
on 'v2/buscar_por_ubicacion', param('estado'), param('municipio') do |estado, municipio|
3738
res.headers['Cache-Control'] = 'max-age=525600, public'
3839
res.headers['Access-Control-Allow-Origin'] = '*'
3940
colonia = req.params['colonia'] # Optional parameter
40-
res.write PostalCodes.fetch_by_location(estado, municipio, colonia)
41+
limit = req.params['limit']&.to_i
42+
res.write PostalCodes.fetch_by_location(estado, municipio, colonia, limit)
4143
end
4244
end
4345
end

models/postal_code.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
class PostalCode < ActiveRecord::Base
22
self.table_name = 'codigos_postales'
33

4-
scope :with_code, -> (code) { where(codigo_postal: code) }
4+
scope :with_code, ->(code) { where(codigo_postal: code) }
55

6-
def self.with_code_hint(code_hint)
7-
where('codigo_postal LIKE :prefix', prefix: "#{code_hint}%")
8-
.order(codigo_postal: :asc)
9-
.distinct
10-
.pluck(:codigo_postal)
6+
def self.with_code_hint(code_hint, limit = nil)
7+
query = where('codigo_postal LIKE :prefix', prefix: "#{code_hint}%")
8+
.order(codigo_postal: :asc)
9+
.distinct
10+
11+
query = query.limit(limit) if limit&.positive?
12+
query.pluck(:codigo_postal)
1113
end
1214

1315
def self.get_suburbs_for(code)

presenters/postal_codes.rb

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
module PostalCodes
2-
def self.fetch_codes(code)
3-
postal_codes = search_postal_codes(code)
2+
def self.fetch_codes(code, limit = nil)
3+
postal_codes = search_postal_codes(code, limit)
44
serialize('codigos_postales' => postal_codes)
55
end
66

7-
def self.search_postal_codes(code)
8-
PostalCode.with_code_hint(code)
7+
def self.search_postal_codes(code, limit = nil)
8+
PostalCode.with_code_hint(code, limit)
99
end
1010

1111
def self.fetch_locations(code)
@@ -15,40 +15,44 @@ def self.fetch_locations(code)
1515
serialize(locations_json)
1616
end
1717

18-
def self.fetch_by_location(estado, municipio, colonia = nil)
19-
postal_codes = search_by_location(estado, municipio, colonia)
18+
def self.fetch_by_location(estado, municipio, colonia = nil, limit = nil)
19+
postal_codes = search_by_location(estado, municipio, colonia, limit)
2020
locations_json = prepare_location_search_json(postal_codes, estado, municipio, colonia)
2121
serialize(locations_json)
2222
end
2323

24-
def self.search_by_location(estado, municipio, colonia = nil)
24+
def self.search_by_location(estado, municipio, colonia = nil, limit = nil)
2525
# Use PostgreSQL's unaccent extension for better performance
2626
query = PostalCode
2727

2828
# Find matching estado
29-
matching_estado = query.where("unaccent(lower(estado)) = unaccent(lower(?))", estado).pluck(:estado).first
29+
matching_estado = query.where('unaccent(lower(estado)) = unaccent(lower(?))', estado).pluck(:estado).first
3030

3131
if matching_estado
3232
query = query.where(estado: matching_estado)
3333

3434
# Find matching municipio
35-
matching_municipio = query.where("unaccent(lower(municipio)) = unaccent(lower(?))", municipio).pluck(:municipio).first
35+
matching_municipio = query.where('unaccent(lower(municipio)) = unaccent(lower(?))',
36+
municipio).pluck(:municipio).first
3637

3738
if matching_municipio
3839
query = query.where(municipio: matching_municipio)
3940

4041
# Find matching colonia if provided
4142
matching_colonia = nil
4243
if colonia.present?
43-
matching_colonia = query.where("unaccent(lower(colonia)) = unaccent(lower(?))", colonia).pluck(:colonia).first
44+
matching_colonia = query.where('unaccent(lower(colonia)) = unaccent(lower(?))', colonia).pluck(:colonia).first
4445
query = query.where(colonia: matching_colonia) if matching_colonia
4546
end
4647

48+
postal_codes_query = query.select('DISTINCT codigo_postal').order('codigo_postal ASC')
49+
postal_codes_query = postal_codes_query.limit(limit) if limit&.positive?
50+
4751
{
4852
found_estado: matching_estado,
4953
found_municipio: matching_municipio,
5054
found_colonia: matching_colonia,
51-
postal_codes: query.select('DISTINCT codigo_postal').order('codigo_postal ASC')
55+
postal_codes: postal_codes_query
5256
}
5357
else
5458
{ found_estado: matching_estado, found_municipio: nil, found_colonia: nil, postal_codes: [] }

spec/requests/api_spec.rb

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,35 @@
107107
describe 'GET /v2/buscar' do
108108
let!(:postal_code1) { create(:postal_code, codigo_postal: '12345') }
109109
let!(:postal_code2) { create(:postal_code, codigo_postal: '12346') }
110+
let!(:postal_code3) { create(:postal_code, codigo_postal: '12347') }
111+
let!(:postal_code4) { create(:postal_code, codigo_postal: '12348') }
110112

111113
it 'returns matching postal codes in v2 format' do
112114
get '/v2/buscar?codigo_postal=123'
113115
expect(last_response).to be_ok
114116
expect(last_response.headers['Content-Type']).to include('application/json')
115117

116118
json_response = Oj.load(last_response.body)
117-
puts "Response body: #{last_response.body}"
118-
expect(json_response['codigos_postales']).to match_array(%w[12345 12346])
119+
expect(json_response['codigos_postales']).to match_array(%w[12345 12346 12347 12348])
120+
end
121+
122+
it 'returns limited postal codes when limit parameter is provided' do
123+
get '/v2/buscar?codigo_postal=123&limit=2'
124+
expect(last_response).to be_ok
125+
expect(last_response.headers['Content-Type']).to include('application/json')
126+
127+
json_response = Oj.load(last_response.body)
128+
expect(json_response['codigos_postales'].length).to eq(2)
129+
expect(json_response['codigos_postales']).to include('12345', '12346')
130+
end
131+
132+
it 'returns all postal codes when limit is not a positive number' do
133+
get '/v2/buscar?codigo_postal=123&limit=0'
134+
expect(last_response).to be_ok
135+
136+
json_response = Oj.load(last_response.body)
137+
expect(json_response['codigos_postales'].length).to eq(4)
138+
expect(json_response['codigos_postales']).to match_array(%w[12345 12346 12347 12348])
119139
end
120140
end
121141

@@ -138,6 +158,18 @@
138158
municipio: test_municipio,
139159
colonia: 'Different Colonia')
140160

161+
create(:postal_code,
162+
codigo_postal: '12347',
163+
estado: test_estado,
164+
municipio: test_municipio,
165+
colonia: 'Another Colonia')
166+
167+
create(:postal_code,
168+
codigo_postal: '12348',
169+
estado: test_estado,
170+
municipio: test_municipio,
171+
colonia: 'Yet Another Colonia')
172+
141173
# Create a postal code with different estado
142174
create(:postal_code,
143175
codigo_postal: '54321',
@@ -154,7 +186,27 @@
154186

155187
json_response = Oj.load(last_response.body)
156188
expect(json_response).to have_key('codigos_postales')
157-
expect(json_response['codigos_postales']).to match_array(%w[12345 12346])
189+
expect(json_response['codigos_postales']).to match_array(%w[12345 12346 12347 12348])
190+
end
191+
192+
it 'returns limited postal codes when limit parameter is provided' do
193+
get "/v2/buscar_por_ubicacion?estado=#{test_estado}&municipio=#{test_municipio}&limit=2"
194+
expect(last_response).to be_ok
195+
expect(last_response.headers['Content-Type']).to include('application/json')
196+
197+
json_response = Oj.load(last_response.body)
198+
expect(json_response).to have_key('codigos_postales')
199+
expect(json_response['codigos_postales'].length).to eq(2)
200+
end
201+
202+
it 'returns all postal codes when limit is not a positive number' do
203+
get "/v2/buscar_por_ubicacion?estado=#{test_estado}&municipio=#{test_municipio}&limit=0"
204+
expect(last_response).to be_ok
205+
206+
json_response = Oj.load(last_response.body)
207+
expect(json_response).to have_key('codigos_postales')
208+
expect(json_response['codigos_postales'].length).to eq(4)
209+
expect(json_response['codigos_postales']).to match_array(%w[12345 12346 12347 12348])
158210
end
159211
end
160212

@@ -167,6 +219,27 @@
167219
expect(json_response).to have_key('codigos_postales')
168220
expect(json_response['codigos_postales']).to match_array(['12345'])
169221
end
222+
223+
it 'applies limit parameter correctly with colonia filter' do
224+
# Creating additional postal codes for the same colonia
225+
create(:postal_code,
226+
codigo_postal: '12349',
227+
estado: test_estado,
228+
municipio: test_municipio,
229+
colonia: test_colonia)
230+
create(:postal_code,
231+
codigo_postal: '12350',
232+
estado: test_estado,
233+
municipio: test_municipio,
234+
colonia: test_colonia)
235+
236+
get "/v2/buscar_por_ubicacion?estado=#{test_estado}&municipio=#{test_municipio}&colonia=#{test_colonia}&limit=2"
237+
expect(last_response).to be_ok
238+
239+
json_response = Oj.load(last_response.body)
240+
expect(json_response).to have_key('codigos_postales')
241+
expect(json_response['codigos_postales'].length).to eq(2)
242+
end
170243
end
171244

172245
context 'without authentication' do

0 commit comments

Comments
 (0)