Skip to content

Commit

Permalink
Resolve #414 Add Language Support (#474)
Browse files Browse the repository at this point in the history
* Return question text and response text in English by default, but use the headers provided by ACCEPT_LANGUAGE to pick the available language or the langPref param.
* Raise exception on SurveyQuestion if language does not exist
* Throw exception on survey show method if lang isn't available
* Include localized response options as well
* Update survey index method to only include id, title, timestamp and url

---------

Co-authored-by: Linden Huhmann <[email protected]>
Co-authored-by: Mike Lynch <[email protected]>
Co-authored-by: Sunnkist <[email protected]>
Co-authored-by: Mike Lynch <[email protected]>
Co-authored-by: Anna Westland-Tegart <[email protected]>
  • Loading branch information
6 people authored Oct 18, 2023
1 parent d840dcb commit 0635239
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 96 deletions.
4 changes: 3 additions & 1 deletion backend/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ gem 'bootsnap', require: false
gem 'devise'
gem 'devise-jwt'
gem 'faraday'
gem 'http_accept_language'
gem 'jbuilder'
gem 'newrelic_rpm'
gem 'pg', '~> 1.1'
gem 'puma', '~> 5.0'
gem 'rack', '~> 2.0'
gem 'rack-cors', '~> 2.0'
gem 'rails', '~> 7.0.3', '>= 7.0.3.1'
gem 'rails', '>= 7.0'
gem 'sprockets-rails'
gem 'sucker_punch', '~> 3.0'
gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]
Expand Down
180 changes: 98 additions & 82 deletions backend/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,74 +1,83 @@
GEM
remote: https://rubygems.org/
specs:
actioncable (7.0.8)
actionpack (= 7.0.8)
activesupport (= 7.0.8)
actioncable (7.1.0)
actionpack (= 7.1.0)
activesupport (= 7.1.0)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.8)
actionpack (= 7.0.8)
activejob (= 7.0.8)
activerecord (= 7.0.8)
activestorage (= 7.0.8)
activesupport (= 7.0.8)
zeitwerk (~> 2.6)
actionmailbox (7.1.0)
actionpack (= 7.1.0)
activejob (= 7.1.0)
activerecord (= 7.1.0)
activestorage (= 7.1.0)
activesupport (= 7.1.0)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.0.8)
actionpack (= 7.0.8)
actionview (= 7.0.8)
activejob (= 7.0.8)
activesupport (= 7.0.8)
actionmailer (7.1.0)
actionpack (= 7.1.0)
actionview (= 7.1.0)
activejob (= 7.1.0)
activesupport (= 7.1.0)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.8)
actionview (= 7.0.8)
activesupport (= 7.0.8)
rack (~> 2.0, >= 2.2.4)
rails-dom-testing (~> 2.2)
actionpack (7.1.0)
actionview (= 7.1.0)
activesupport (= 7.1.0)
nokogiri (>= 1.8.5)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (7.0.8)
actionpack (= 7.0.8)
activerecord (= 7.0.8)
activestorage (= 7.0.8)
activesupport (= 7.0.8)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
actiontext (7.1.0)
actionpack (= 7.1.0)
activerecord (= 7.1.0)
activestorage (= 7.1.0)
activesupport (= 7.1.0)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.8)
activesupport (= 7.0.8)
actionview (7.1.0)
activesupport (= 7.1.0)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (7.0.8)
activesupport (= 7.0.8)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.1.0)
activesupport (= 7.1.0)
globalid (>= 0.3.6)
activemodel (7.0.8)
activesupport (= 7.0.8)
activerecord (7.0.8)
activemodel (= 7.0.8)
activesupport (= 7.0.8)
activestorage (7.0.8)
actionpack (= 7.0.8)
activejob (= 7.0.8)
activerecord (= 7.0.8)
activesupport (= 7.0.8)
activemodel (7.1.0)
activesupport (= 7.1.0)
activerecord (7.1.0)
activemodel (= 7.1.0)
activesupport (= 7.1.0)
timeout (>= 0.4.0)
activestorage (7.1.0)
actionpack (= 7.1.0)
activejob (= 7.1.0)
activerecord (= 7.1.0)
activesupport (= 7.1.0)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.8)
activesupport (7.1.0)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
ast (2.4.2)
base64 (0.1.1)
bcrypt (3.1.19)
bigdecimal (3.1.4)
bindex (0.8.1)
bootsnap (1.16.0)
msgpack (~> 1.2)
Expand All @@ -80,6 +89,7 @@ GEM
bundler (>= 1.2.0, < 3)
thor (~> 1.0)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
crass (1.0.6)
date (3.3.3)
debug (1.8.0)
Expand All @@ -95,6 +105,8 @@ GEM
devise (~> 4.0)
warden-jwt_auth (~> 0.8)
diff-lcs (1.5.0)
drb (2.1.1)
ruby2_keywords
dry-auto_inject (1.0.1)
dry-core (~> 1.0)
zeitwerk (~> 2.6)
Expand All @@ -117,6 +129,7 @@ GEM
faraday-net_http (3.0.2)
globalid (1.2.1)
activesupport (>= 6.1)
http_accept_language (2.1.1)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
io-console (0.6.0)
Expand All @@ -129,7 +142,7 @@ GEM
json (2.6.3)
jwt (2.7.1)
language_server-protocol (3.17.0.3)
loofah (2.21.3)
loofah (2.21.4)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
mail (2.8.1)
Expand All @@ -138,11 +151,11 @@ GEM
net-pop
net-smtp
marcel (1.0.2)
method_source (1.0.0)
mini_mime (1.1.5)
minitest (5.20.0)
msgpack (1.7.2)
net-imap (0.3.7)
mutex_m (0.1.2)
net-imap (0.4.1)
date
net-protocol
net-pop (0.1.2)
Expand All @@ -153,15 +166,11 @@ GEM
net-protocol
newrelic_rpm (9.5.0)
nio4r (2.5.9)
nokogiri (1.15.4-arm64-darwin)
racc (~> 1.4)
nokogiri (1.15.4-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.15.4-x86_64-linux)
racc (~> 1.4)
orm_adapter (0.5.0)
parallel (1.23.0)
parser (3.2.2.3)
parser (3.2.2.4)
ast (~> 2.4.1)
racc
pg (1.5.4)
Expand All @@ -173,42 +182,48 @@ GEM
rack (2.2.8)
rack-cors (2.0.1)
rack (>= 2.0.0)
rack-session (1.0.1)
rack (< 3)
rack-test (2.1.0)
rack (>= 1.3)
rails (7.0.8)
actioncable (= 7.0.8)
actionmailbox (= 7.0.8)
actionmailer (= 7.0.8)
actionpack (= 7.0.8)
actiontext (= 7.0.8)
actionview (= 7.0.8)
activejob (= 7.0.8)
activemodel (= 7.0.8)
activerecord (= 7.0.8)
activestorage (= 7.0.8)
activesupport (= 7.0.8)
rackup (1.0.0)
rack (< 3)
webrick
rails (7.1.0)
actioncable (= 7.1.0)
actionmailbox (= 7.1.0)
actionmailer (= 7.1.0)
actionpack (= 7.1.0)
actiontext (= 7.1.0)
actionview (= 7.1.0)
activejob (= 7.1.0)
activemodel (= 7.1.0)
activerecord (= 7.1.0)
activestorage (= 7.1.0)
activesupport (= 7.1.0)
bundler (>= 1.15.0)
railties (= 7.0.8)
railties (= 7.1.0)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
railties (7.0.8)
actionpack (= 7.0.8)
activesupport (= 7.0.8)
method_source
railties (7.1.0)
actionpack (= 7.1.0)
activesupport (= 7.1.0)
irb
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.0.6)
rdoc (6.5.0)
psych (>= 4.0.0)
regexp_parser (2.8.1)
reline (0.3.8)
regexp_parser (2.8.2)
reline (0.3.9)
io-console (~> 0.5)
responders (3.1.0)
actionpack (>= 5.2)
Expand All @@ -231,7 +246,7 @@ GEM
rspec-mocks (~> 3.12)
rspec-support (~> 3.12)
rspec-support (3.12.1)
rubocop (1.56.3)
rubocop (1.56.4)
base64 (~> 0.1.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
Expand All @@ -245,7 +260,7 @@ GEM
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.29.0)
parser (>= 3.2.1.0)
rubocop-rails (2.21.1)
rubocop-rails (2.21.2)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
Expand All @@ -267,7 +282,7 @@ GEM
timeout (0.4.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.4.2)
unicode-display_width (2.5.0)
warden (1.2.9)
rack (>= 2.0.9)
warden-jwt_auth (0.8.0)
Expand All @@ -280,14 +295,13 @@ GEM
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webrick (1.8.1)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
zeitwerk (2.6.12)

PLATFORMS
arm64-darwin-21
universal-darwin-22
x86_64-linux

DEPENDENCIES
Expand All @@ -299,12 +313,14 @@ DEPENDENCIES
devise-jwt
factory_bot_rails
faraday
http_accept_language
jbuilder
newrelic_rpm
pg (~> 1.1)
puma (~> 5.0)
rack (~> 2.0)
rack-cors (~> 2.0)
rails (~> 7.0.3, >= 7.0.3.1)
rails (>= 7.0)
rspec-rails (~> 6.0.0)
rubocop
rubocop-rails
Expand All @@ -316,7 +332,7 @@ DEPENDENCIES
web-console

RUBY VERSION
ruby 3.1.3p185
ruby 3.1.4p223

BUNDLED WITH
2.3.24
2.3.26
12 changes: 11 additions & 1 deletion backend/app/controllers/surveys_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

class SurveysController < ApplicationController
AVAILABLE_LANGUAGES = %w[en es fr-ht pt-br].freeze
before_action :set_survey, only: %i[show edit update destroy]

# GET /surveys or /surveys.json
Expand All @@ -9,7 +10,16 @@ def index
end

# GET /surveys/1 or /surveys/1.json
def show; end
def show
@language_code = (params[:langPref].presence || http_accept_language.preferred_language_from(AVAILABLE_LANGUAGES))

# If first question of survey doesn't have this localization, then throw exception
# (No need to check all questions for this localization)
return unless @survey.survey_questions.first.localized_survey_questions.find_by(language_code: @language_code).nil?

raise StandardError,
"Survey question #{@survey.id} does not have localization '#{@language_code}'"
end

# GET /surveys/new
def new
Expand Down
5 changes: 5 additions & 0 deletions backend/app/models/localized_survey_question.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class LocalizedSurveyQuestion < ApplicationRecord
belongs_to :survey_question
end
Loading

0 comments on commit 0635239

Please sign in to comment.