Skip to content
Open
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
17 changes: 17 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
AllCops:
Exclude:
- bin/**/*
- db/**/*
- spec/**/**/**/*
- vendor/**/*
NewCops: enable
SuggestExtensions: false

Style/Documentation:
Enabled: false

Metrics/MethodLength:
Max: 20

Metrics/AbcSize:
Max: 20
25 changes: 15 additions & 10 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
source "https://rubygems.org"
# frozen_string_literal: true

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.2.1"
ruby '3.2.1'

gem "rails", "~> 7.0.4", ">= 7.0.4.2"
gem "mysql2", "~> 0.5"
gem "puma", "~> 5.0"
gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]
gem "bootsnap", require: false
gem 'bootsnap', require: false
gem 'flatten'
gem 'mysql2', '~> 0.5'
gem 'puma', '~> 5.0'
gem 'rails', '~> 7.0.4', '>= 7.0.4.2'
gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]

group :development, :test do
gem "debug", platforms: %i[ mri mingw x64_mingw ]
gem "rspec-rails"
gem 'debug', platforms: %i[mri mingw x64_mingw]
gem 'pry-rails'
gem 'rspec-rails'
gem 'shoulda-matchers'
end

group :development do
gem 'pry'
gem 'rubocop', require: false
end
32 changes: 31 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ GEM
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
ast (2.4.2)
bootsnap (1.16.0)
msgpack (~> 1.2)
builder (3.2.4)
Expand All @@ -76,10 +77,12 @@ GEM
debug (1.7.1)
diff-lcs (1.5.0)
erubi (1.12.0)
flatten (0.2.0)
globalid (1.1.0)
activesupport (>= 5.0)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
json (2.6.3)
loofah (2.19.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
Expand All @@ -106,9 +109,14 @@ GEM
nio4r (2.5.8)
nokogiri (1.14.2-x86_64-darwin)
racc (~> 1.4)
parallel (1.22.1)
parser (3.2.1.0)
ast (~> 2.4.1)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
puma (5.6.5)
nio4r (~> 2.0)
racc (1.6.2)
Expand Down Expand Up @@ -141,7 +149,10 @@ GEM
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.7.0)
rexml (3.2.5)
rspec-core (3.12.1)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.2)
Expand All @@ -159,10 +170,26 @@ GEM
rspec-mocks (~> 3.11)
rspec-support (~> 3.11)
rspec-support (3.12.0)
rubocop (1.45.1)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.2.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.24.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.26.0)
parser (>= 3.2.1.0)
ruby-progressbar (1.11.0)
shoulda-matchers (5.3.0)
activesupport (>= 5.2.0)
thor (1.2.1)
timeout (0.3.2)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.4.2)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
Expand All @@ -174,11 +201,14 @@ PLATFORMS
DEPENDENCIES
bootsnap
debug
flatten
mysql2 (~> 0.5)
pry
pry-rails
puma (~> 5.0)
rails (~> 7.0.4, >= 7.0.4.2)
rspec-rails
rubocop
shoulda-matchers
tzinfo-data

RUBY VERSION
Expand Down
4 changes: 3 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require_relative "config/application"
require_relative 'config/application'

Rails.application.load_tasks
2 changes: 2 additions & 0 deletions app/channels/application_cable/channel.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module ApplicationCable
class Channel < ActionCable::Channel::Base
end
Expand Down
2 changes: 2 additions & 0 deletions app/channels/application_cable/connection.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module ApplicationCable
class Connection < ActionCable::Connection::Base
end
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# frozen_string_literal: true

class ApplicationController < ActionController::API
end
54 changes: 54 additions & 0 deletions app/controllers/reservations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

class ReservationsController < ApplicationController
LOOKUP_ITEMS = YAML.load_file('lib/lookup.yml').deep_symbolize_keys

def create
data = parse_data(JSON.parse(request.body.read).smash)

guest = create_or_update_guest(data[:guest])

unless guest.valid?
render json: { success: false, errors: guest.errors }
return
end

reservation = create_or_update_reservation(data[:reservation], guest.id)

unless reservation.valid?
render json: { success: false, errors: reservation.errors }
return
end

render json: { success: true, guest:, reservation: }
end

private

def parse_data(data)
guest = {}
reservation = {}

data.each do |key, value|
record = LOOKUP_ITEMS[key.to_sym]
next if record.blank?

reservation[record[:property].to_sym] = value if record[:model] == 'reservation'
guest[record[:property].to_sym] = value if record[:model] == 'guest'
end

reservation[:guest_id] = guest[:id]
{ reservation:, guest: }
end

def create_or_update_guest(data)
Guest.upsert(data)
Guest.find_by(email: data[:email])
end

def create_or_update_reservation(data, guest_id)
data[:guest_id] = guest_id
Reservation.upsert(data)
Reservation.find_by(code: data[:code])
end
end
2 changes: 2 additions & 0 deletions app/jobs/application_job.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

class ApplicationJob < ActiveJob::Base
# Automatically retry jobs that encountered a deadlock
# retry_on ActiveRecord::Deadlocked
Expand Down
6 changes: 4 additions & 2 deletions app/mailers/application_mailer.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# frozen_string_literal: true

class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
layout "mailer"
default from: 'from@example.com'
layout 'mailer'
end
2 changes: 2 additions & 0 deletions app/models/application_record.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
end
12 changes: 12 additions & 0 deletions app/models/guest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class Guest < ApplicationRecord
has_many :reservations

validates :first_name,
:last_name,
:phone,
:email, presence: true

validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }, uniqueness: true
end
18 changes: 18 additions & 0 deletions app/models/reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

class Reservation < ApplicationRecord
belongs_to :guest

validates :code,
:date_start,
:date_end,
:number_adults,
:number_children,
:number_infants,
:amount_payout,
:amount_security,
:currency,
:status, presence: true

validates :code, uniqueness: true
end
40 changes: 22 additions & 18 deletions bin/bundle
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,57 @@
# this file is here to facilitate running it.
#

require "rubygems"
require 'rubygems'

m = Module.new do
module_function

def invoked_as_script?
File.expand_path($0) == File.expand_path(__FILE__)
File.expand_path($PROGRAM_NAME) == File.expand_path(__FILE__)
end

def env_var_version
ENV["BUNDLER_VERSION"]
ENV['BUNDLER_VERSION']
end

def cli_arg_version
return unless invoked_as_script? # don't want to hijack other binstubs
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
return unless 'update'.start_with?(ARGV.first || ' ') # must be running `bundle update`

bundler_version = nil
update_index = nil
ARGV.each_with_index do |a, i|
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
bundler_version = a
end
bundler_version = a if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
bundler_version = $1

bundler_version = Regexp.last_match(1)
update_index = i
end
bundler_version
end

def gemfile
gemfile = ENV["BUNDLE_GEMFILE"]
gemfile = ENV['BUNDLE_GEMFILE']
return gemfile if gemfile && !gemfile.empty?

File.expand_path("../Gemfile", __dir__)
File.expand_path('../Gemfile', __dir__)
end

def lockfile
lockfile =
case File.basename(gemfile)
when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
when 'gems.rb' then gemfile.sub(/\.rb$/, gemfile)
else "#{gemfile}.lock"
end
File.expand_path(lockfile)
end

def lockfile_version
return unless File.file?(lockfile)

lockfile_contents = File.read(lockfile)
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/

Regexp.last_match(1)
end

Expand All @@ -76,20 +78,24 @@ m = Module.new do
end

def load_bundler!
ENV["BUNDLE_GEMFILE"] ||= gemfile
ENV['BUNDLE_GEMFILE'] ||= gemfile

activate_bundler
end

def activate_bundler
gem_error = activation_error_handling do
gem "bundler", bundler_requirement
gem 'bundler', bundler_requirement
end
return if gem_error.nil?

require_error = activation_error_handling do
require "bundler/version"
require 'bundler/version'
end
if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
return
end
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))

warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
exit 42
end
Expand All @@ -104,6 +110,4 @@ end

m.load_bundler!

if m.invoked_as_script?
load Gem.bin_path("bundler", "bundle")
end
load Gem.bin_path('bundler', 'bundle') if m.invoked_as_script?
8 changes: 5 additions & 3 deletions bin/rails
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/usr/bin/env ruby
APP_PATH = File.expand_path("../config/application", __dir__)
require_relative "../config/boot"
require "rails/commands"
# frozen_string_literal: true

APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'
Loading