Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Results page #36

Merged
merged 6 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ on: [push]

env:
RAILS_ENV: test
GOOGLE_MAP_API_KEY: notusedinspecs
SECRET_KEY_BASE: notusedinspecs

jobs:
rspec:
Expand Down Expand Up @@ -35,6 +37,9 @@ jobs:
with:
node-version: '16.20.0'

- name: Install dependencies
run: sudo apt-get install -y libproj-dev proj-bin

- name: Set up ruby gem cache
uses: actions/cache@v3
with:
Expand Down Expand Up @@ -102,6 +107,9 @@ jobs:
restore-keys: |
${{ runner.os }}-gems-

- name: Install dependencies
run: sudo apt-get install -y libproj-dev proj-bin

- name: Install gems
run: |
bundle config path vendor/bundle
Expand Down Expand Up @@ -139,6 +147,9 @@ jobs:
restore-keys: |
${{ runner.os }}-gems-

- name: Install dependencies
run: sudo apt-get install -y libproj-dev proj-bin

- name: Install gems
run: |
bundle config path vendor/bundle
Expand Down
22 changes: 12 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
# production: runs the actual app

# Build builder image
FROM ruby:3.2.2-alpine as builder
FROM ruby:3.1.2-alpine as builder

# RUN apk -U upgrade && \
# apk add --update --no-cache gcc git libc6-compat libc-dev make nodejs \
# postgresql13-dev yarn
RUN apk -U upgrade && \
apk add --update --no-cache gcc git libc6-compat libc-dev make nodejs \
postgresql13-dev yarn

WORKDIR /app

Expand All @@ -20,6 +20,8 @@ RUN apk add --update --no-cache tzdata && \
# yarn: node package manager
# postgresql-dev: postgres driver and libraries
RUN apk add --no-cache build-base yarn postgresql13-dev
RUN apk add --no-cache proj-dev
#RUN apk add --no-cache libproj-dev proj-bin

# Install gems defined in Gemfile
COPY .ruby-version Gemfile Gemfile.lock ./
Expand All @@ -39,6 +41,7 @@ RUN yarn install --frozen-lockfile --check-files
# Copy all files to /app (except what is defined in .dockerignore)
COPY . .

ENV GOOGLE_MAP_API_KEY="just-for-assets"
# Precompile assets
RUN RAILS_ENV=production SECRET_KEY_BASE=required-to-run-but-not-used \
bundle exec rails assets:precompile
Expand All @@ -53,22 +56,21 @@ RUN rm -rf node_modules log/* tmp/* /tmp && \
find /usr/local/bundle/gems -name "*.html" -delete

# Build runtime image
FROM ruby:3.2.2-alpine as production
FROM ruby:3.1.2-alpine as production

# The application runs from /app
WORKDIR /app

# Add the timezone (prod image) as it's not configured by default in Alpine
RUN apk add --update --no-cache tzdata && \
cp /usr/share/zoneinfo/Europe/London /etc/localtime && \
echo "Europe/London" > /etc/timezone
RUN apk add --update --no-cache tzdata && cp /usr/share/zoneinfo/Europe/London /etc/localtime && echo "Europe/London" > /etc/timezone

# libpq: required to run postgres
RUN apk add --no-cache libpq
RUN apk add --no-cache proj-dev

# Copy files generated in the builder image
COPY --from=builder /app /app
COPY --from=builder /usr/local/bundle/ /usr/local/bundle/

CMD bundle exec rails db:migrate && \
bundle exec rails server -b 0.0.0.0
CMD RAILS_ENV=production bundle exec rails db:migrate && \
RAILS_ENV=production bundle exec rails server -b 0.0.0.0
5 changes: 5 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ ruby "3.1.2"
gem "activerecord-postgis-adapter"
gem "bootsnap", require: false
gem "bundler", "~> 2.4"
gem 'geocoder'
gem "pg", "~> 1.1"
gem "puma", "~> 5.0"
gem "rails", "~> 7.0.4", ">= 7.0.4.3"
gem "rgeo"
gem "rgeo-geojson"
gem "rgeo-proj4"

gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]

gem "cssbundling-rails"
Expand All @@ -36,6 +39,8 @@ end
group :test, :development do
gem "byebug"
gem "dotenv-rails"
gem "pry"
gem "pry-byebug"
gem "rspec"
gem "rspec-rails"
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
Expand Down
14 changes: 14 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
coderay (1.1.3)
concurrent-ruby (1.2.2)
crass (1.0.6)
cssbundling-rails (1.1.2)
Expand All @@ -101,6 +102,7 @@ GEM
dotenv (= 2.8.1)
railties (>= 3.2)
erubi (1.12.0)
geocoder (1.8.2)
globalid (1.1.0)
activesupport (>= 5.0)
govuk-components (4.0.0)
Expand Down Expand Up @@ -161,6 +163,12 @@ GEM
activesupport (>= 7.0.0)
rack
railties (>= 7.0.0)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.10.1)
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
public_suffix (5.0.1)
puma (5.6.5)
nio4r (~> 2.0)
Expand Down Expand Up @@ -207,6 +215,8 @@ GEM
rgeo (>= 1.0.0)
rgeo-geojson (2.1.1)
rgeo (>= 1.0.0)
rgeo-proj4 (4.0.0)
rgeo (~> 3.0.0)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
Expand Down Expand Up @@ -305,16 +315,20 @@ DEPENDENCIES
cssbundling-rails
debug
dotenv-rails
geocoder
govuk-components
govuk_design_system_formbuilder
jsbundling-rails
pg (~> 1.1)
prettier_print
propshaft
pry
pry-byebug
puma (~> 5.0)
rails (~> 7.0.4, >= 7.0.4.3)
rgeo
rgeo-geojson
rgeo-proj4
rspec
rspec-rails
rubocop-govuk
Expand Down
9 changes: 9 additions & 0 deletions app/assets/stylesheets/application.sass.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,12 @@ $govuk-new-link-styles: true;
$govuk-assets-path: "/";

@import "govuk-frontend/govuk/all";

.hub-results {
border-top: 1px solid govuk-colour("mid-grey");

.hub-result {
padding-top: 20px;
border-bottom: 1px solid govuk-colour("mid-grey");
}
}
6 changes: 6 additions & 0 deletions app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
class PagesController < ApplicationController
def home
end

def privacy_policy
end

def cookies
end
end
12 changes: 7 additions & 5 deletions app/controllers/search_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ def form
def results
@search = SearchForm.new(params.permit(:location) )

if @search.valid?
raise NotImplementedError
else
render 'form', status: :unprocessable_entity
end
render 'form', status: :unprocessable_entity unless @search.valid?
end

def validate
@names = LocalAuthority.pluck(:name)
@hubs = Hub.all
end

end
2 changes: 1 addition & 1 deletion app/lib/hub/importer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def get_local_authorities(string)
inversed_map = @authorities_with_comas_map.invert

mapped.split(', ').map do |str|
inversed_map[str] || ALIASES[str] || str
inversed_map[str] || str
end
end

Expand Down
43 changes: 43 additions & 0 deletions app/lib/local_authority/search.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
class LocalAuthority::Search
def initialize(scope, query)
@scope = scope
@query = query
end

def call
result = @scope.order_by_distance_from(search_centre)

if search_polygon
result.where("ST_Intersects(geometry, ?)", search_polygon)
else
result.limit(5)
end
end

def search_centre
transform RGeo::Geographic.spherical_factory.point(geo_result.longitude, geo_result.latitude)
end

def geo_result
@geo_result ||= Geocoder.search("#{@query}, UK", params: {limit: 1, polygon_geojson: 1, countrycodes: 'gb'}).first
end

def search_polygon
return @search_polygon if defined? @search_polygon

#binding.pry
json = geo_result && geo_result.data['geojson']
return @search_polygon = nil unless json

transform RGeo::GeoJSON.decode(json.to_json)
end

def transform(geo)
RGeo::CoordSys::Proj4.transform(
RGeo::CoordSys::Proj4.new("EPSG:4326"),
geo,
RGeo::CoordSys::Proj4.new("EPSG:27700"),
RGeo::Cartesian.preferred_factory
)
end
end
3 changes: 3 additions & 0 deletions app/models/hub.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
class Hub < ApplicationRecord
def self.by_local_authority(*authorities)
where("areas && ARRAY[?]::varchar[]", authorities)
end
end
9 changes: 9 additions & 0 deletions app/models/local_authority.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
class LocalAuthority < ApplicationRecord
include RGeo::ActiveRecord::GeometryMixin

def self.search(query)
Search.new(self, query).call
end

def self.order_by_distance_from(point)
order(Arel.sql("geometry <-> ST_Geomfromtext('#{sanitize_sql(point.as_text)}')"))
end
end
5 changes: 5 additions & 0 deletions app/models/search_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ class SearchForm
attribute :location

validates :location, presence: true

def hubs
authorities = LocalAuthority.search(location)
Hub.by_local_authority(*authorities.pluck(:name))
end
end
16 changes: 15 additions & 1 deletion app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
<!DOCTYPE html>
<html lang="en" class="govuk-template">
<head>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-N58Z5PG');</script>
<!-- End Google Tag Manager -->
<title><%= [yield(:page_title).presence, t('service.name')].compact.join(' - ') %></title>

<%= csrf_meta_tags %>
Expand All @@ -21,6 +28,10 @@
</head>

<body class="govuk-template__body">
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-N58Z5PG"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<script>
document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');
</script>
Expand All @@ -35,6 +46,9 @@
</main>
</div>

<%= govuk_footer %>
<%= govuk_footer(meta_items:
[{href: "/pages/privacy-policy", text: "Privacy Policy"},
{href: "/pages/cookies", text: "Cookies"}])
%>
</body>
</html>
Loading
Loading