Skip to content

Commit

Permalink
Merge pull request #1796 from unboxed/public-api
Browse files Browse the repository at this point in the history
Create public planning applications controller with search action for API
  • Loading branch information
benbaumann95 authored May 15, 2024
2 parents a92b0eb + 955408c commit e46acb7
Show file tree
Hide file tree
Showing 14 changed files with 422 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

module BopsApi
module V2
module Public
class PlanningApplicationsController < PublicController
def search
@pagy, @planning_applications = search_service.call

respond_to do |format|
format.json
end
end

private

def planning_applications_scope
@local_authority.planning_applications.where(make_public: true)
end

def search_params
params.permit(:page, :maxresults, :q)
end

def search_service(scope = planning_applications_scope.by_created_at_desc)
@search_service ||= Application::SearchService.new(scope, search_params)
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

module BopsApi
module V2
class PublicController < ApplicationController
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@
module BopsApi
module Application
class QueryService
include Pagy::Backend

DEFAULT_PAGE = 1
DEFAULT_MAXRESULTS = 10
MAXRESULTS_LIMIT = 20

def initialize(scope, params)
@scope = scope
@params = params
Expand All @@ -17,7 +11,7 @@ def initialize(scope, params)
attr_reader :scope, :params

def call
paginate(filter_by_ids)
Pagination.new(scope: filter_by_ids, params:).paginate
end

private
Expand All @@ -27,13 +21,6 @@ def filter_by_ids

scope.where(id: params[:ids])
end

def paginate(scope)
page = (params[:page] || DEFAULT_PAGE).to_i
maxresults = [(params[:maxresults] || DEFAULT_MAXRESULTS).to_i, MAXRESULTS_LIMIT].min

pagy(scope, page:, items: maxresults)
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true

module BopsApi
module Application
class SearchService
def initialize(scope, params)
@scope = scope
@params = params
@query = params[:q]
end

attr_reader :scope, :params, :query

def call
Pagination.new(scope: search, params:).paginate
end

private

def search
return scope if query.blank?

search_reference.presence || search_description
end

def search_reference
scope.where(
"LOWER(reference) LIKE ?",
"%#{query.downcase}%"
)
end

def search_description
scope.select(sanitized_select_sql)
.where(where_sql, query_terms)
.order(rank: :desc)
end

def sanitized_select_sql
ActiveRecord::Base.sanitize_sql_array([select_sql, query_terms])
end

def select_sql
"planning_applications.*,
ts_rank(
to_tsvector('english', description),
to_tsquery('english', ?)
) AS rank"
end

def where_sql
"to_tsvector('english', description) @@ to_tsquery('english', ?)"
end

def query_terms
@query_terms ||= query.split.join(" | ")
end
end
end
end
27 changes: 27 additions & 0 deletions engines/bops_api/app/views/bops_api/v2/public/_show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

json.application do
json.type do
json.value planning_application.application_type.code
json.description planning_application.application_type.name
end
json.reference planning_application.reference
json.full_reference planning_application.reference_in_full
end
json.property do
json.address do
json.latitude planning_application.latitude
json.longitude planning_application.longitude
json.title planning_application.address_1
json.singleLine planning_application.full_address
json.uprn planning_application.uprn
json.town planning_application.town
json.postcode planning_application.postcode
end
json.boundary do
json.site planning_application.boundary_geojson
end
end
json.proposal do
json.description planning_application.description
end
14 changes: 14 additions & 0 deletions engines/bops_api/app/views/bops_api/v2/public/search.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

json.metadata do
json.page @pagy.page
json.results @pagy.items
json.from @pagy.from
json.to @pagy.to
json.total_pages @pagy.pages
json.total_results @pagy.count
end

json.data @planning_applications.each do |planning_application|
json.partial! "show", planning_application:
end
6 changes: 6 additions & 0 deletions engines/bops_api/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
resources :planning_applications, only: [:index, :show, :create] do
get :determined, on: :collection
end

namespace :public do
resources :planning_applications, only: [] do
get :search, on: :collection
end
end
end
end
end
1 change: 1 addition & 0 deletions engines/bops_api/lib/bops_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require "bops_api/engine"
require "bops_api/errors"
require "bops_api/pagination"
require "bops_api/schemas"

module BopsApi
Expand Down
25 changes: 25 additions & 0 deletions engines/bops_api/lib/bops_api/pagination.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module BopsApi
class Pagination
include Pagy::Backend

DEFAULT_PAGE = 1
DEFAULT_MAXRESULTS = 10
MAXRESULTS_LIMIT = 20

def initialize(scope:, params:)
@scope = scope
@params = params
end

attr_reader :scope, :params

def paginate
page = (params[:page] || DEFAULT_PAGE).to_i
maxresults = [(params[:maxresults] || DEFAULT_MAXRESULTS).to_i, MAXRESULTS_LIMIT].min

pagy(scope, page:, items: maxresults)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"metadata": {
"page": 1,
"results": 10,
"from": 1,
"to": 1,
"total_pages": 1,
"total_results": 1
},
"data": [
{
"application": {
"type": {
"value": "pp.full.householder",
"description": "planning_permission"
},
"reference": "24-00620-HAPP",
"full_reference": "SWK-24-00620-HAPP"
},
"property": {
"address": {
"latitude": 51.4656522,
"longitude": -0.1185926,
"title": "40, STANSFIELD ROAD",
"singleLine": "40, STANSFIELD ROAD, LONDON, SW9 9RZ",
"uprn": "100021892955",
"town": "LONDON",
"postcode": "SW9 9RZ"
},
"boundary": {
"site": {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-0.1186569035053321,
51.465703531871384
],
[
-0.1185938715934822,
51.465724418998775
],
[
-0.1184195280075143,
51.46552473766957
],
[
-0.11848390102387167,
51.4655038504508
],
[
-0.1186569035053321,
51.465703531871384
]
]
]
},
"properties": null
}
}
},
"proposal": {
"description": "Roof extension to the rear of the property, incorporating starship launchpad."
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
let(:planning_application) { example_fixture("validPlanningPermission.json") }
let(:send_email) { "true" }

let!(:planning_applications) { create_list(:planning_application, 8, local_authority:, application_type:) }
let!(:planning_applications) { create_list(:planning_application, 8, local_authority:, application_type:, make_public: true) }
let!(:determined_planning_applications) { create_list(:planning_application, 3, :determined, local_authority:, application_type:) }
let(:page) { 2 }
let(:maxresults) { 5 }
Expand Down
Loading

0 comments on commit e46acb7

Please sign in to comment.