Compare commits
1 commit
karol_mast
...
master
Author | SHA1 | Date | |
---|---|---|---|
efdd42b492 |
112 changed files with 373 additions and 1428 deletions
1
.rspec
1
.rspec
|
@ -1 +0,0 @@
|
||||||
--require spec_helper
|
|
19
Gemfile
19
Gemfile
|
@ -1,12 +1,10 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
||||||
|
|
||||||
ruby '2.7.2'
|
ruby '2.7.2'
|
||||||
|
|
||||||
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
|
||||||
gem 'rails', '~> 6.1.3'
|
gem 'rails', '~> 6.1.7.6'
|
||||||
# Use sqlite3 as the database for Active Record
|
# Use sqlite3 as the database for Active Record
|
||||||
gem 'sqlite3', '~> 1.4'
|
gem 'sqlite3', '~> 1.4'
|
||||||
# Use Puma as the app server
|
# Use Puma as the app server
|
||||||
|
@ -22,26 +20,19 @@ gem 'jbuilder', '~> 2.7'
|
||||||
# Use Redis adapter to run Action Cable in production
|
# Use Redis adapter to run Action Cable in production
|
||||||
# gem 'redis', '~> 4.0'
|
# gem 'redis', '~> 4.0'
|
||||||
# Use Active Model has_secure_password
|
# Use Active Model has_secure_password
|
||||||
gem 'bcrypt', '~> 3.1.7'
|
# gem 'bcrypt', '~> 3.1.7'
|
||||||
|
|
||||||
gem 'materialize-sass', '~> 1.0.0'
|
gem 'materialize-sass', '~> 1.0.0'
|
||||||
|
|
||||||
gem 'jquery-rails'
|
|
||||||
|
|
||||||
# Use Active Storage variant
|
# Use Active Storage variant
|
||||||
# gem 'image_processing', '~> 1.2'
|
# gem 'image_processing', '~> 1.2'
|
||||||
|
|
||||||
# Reduces boot times through caching; required in config/boot.rb
|
# Reduces boot times through caching; required in config/boot.rb
|
||||||
gem 'bootsnap', '>= 1.4.4', require: false
|
gem 'bootsnap', '>= 1.4.4', require: false
|
||||||
|
|
||||||
gem 'rubocop', require: false
|
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||||
gem 'byebug', platforms: %i[mri mingw x64_mingw]
|
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
|
||||||
gem 'rails-controller-testing'
|
|
||||||
gem 'rspec'
|
|
||||||
gem 'rspec-rails', '>= 2.0.0.beta'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
@ -49,8 +40,8 @@ group :development do
|
||||||
gem 'web-console', '>= 4.1.0'
|
gem 'web-console', '>= 4.1.0'
|
||||||
# Display performance information such as SQL time and flame graphs for each request in your browser.
|
# Display performance information such as SQL time and flame graphs for each request in your browser.
|
||||||
# Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
|
# Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
|
||||||
gem 'listen', '~> 3.3'
|
|
||||||
gem 'rack-mini-profiler', '~> 2.0'
|
gem 'rack-mini-profiler', '~> 2.0'
|
||||||
|
gem 'listen', '~> 3.3'
|
||||||
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
|
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
|
||||||
gem 'spring'
|
gem 'spring'
|
||||||
end
|
end
|
||||||
|
@ -64,4 +55,4 @@ group :test do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||||
gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]
|
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
||||||
|
|
254
Gemfile.lock
254
Gemfile.lock
|
@ -1,60 +1,60 @@
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (6.1.3)
|
actioncable (6.1.7.6)
|
||||||
actionpack (= 6.1.3)
|
actionpack (= 6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
actionmailbox (6.1.3)
|
actionmailbox (6.1.7.6)
|
||||||
actionpack (= 6.1.3)
|
actionpack (= 6.1.7.6)
|
||||||
activejob (= 6.1.3)
|
activejob (= 6.1.7.6)
|
||||||
activerecord (= 6.1.3)
|
activerecord (= 6.1.7.6)
|
||||||
activestorage (= 6.1.3)
|
activestorage (= 6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
mail (>= 2.7.1)
|
mail (>= 2.7.1)
|
||||||
actionmailer (6.1.3)
|
actionmailer (6.1.7.6)
|
||||||
actionpack (= 6.1.3)
|
actionpack (= 6.1.7.6)
|
||||||
actionview (= 6.1.3)
|
actionview (= 6.1.7.6)
|
||||||
activejob (= 6.1.3)
|
activejob (= 6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (6.1.3)
|
actionpack (6.1.7.6)
|
||||||
actionview (= 6.1.3)
|
actionview (= 6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
rack (~> 2.0, >= 2.0.9)
|
rack (~> 2.0, >= 2.0.9)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||||
actiontext (6.1.3)
|
actiontext (6.1.7.6)
|
||||||
actionpack (= 6.1.3)
|
actionpack (= 6.1.7.6)
|
||||||
activerecord (= 6.1.3)
|
activerecord (= 6.1.7.6)
|
||||||
activestorage (= 6.1.3)
|
activestorage (= 6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (6.1.3)
|
actionview (6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||||
activejob (6.1.3)
|
activejob (6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (6.1.3)
|
activemodel (6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
activerecord (6.1.3)
|
activerecord (6.1.7.6)
|
||||||
activemodel (= 6.1.3)
|
activemodel (= 6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
activestorage (6.1.3)
|
activestorage (6.1.7.6)
|
||||||
actionpack (= 6.1.3)
|
actionpack (= 6.1.7.6)
|
||||||
activejob (= 6.1.3)
|
activejob (= 6.1.7.6)
|
||||||
activerecord (= 6.1.3)
|
activerecord (= 6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
marcel (~> 0.3.1)
|
marcel (~> 1.0)
|
||||||
mimemagic (~> 0.3.2)
|
mini_mime (>= 1.1.0)
|
||||||
activesupport (6.1.3)
|
activesupport (6.1.7.6)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
|
@ -62,10 +62,8 @@ GEM
|
||||||
zeitwerk (~> 2.3)
|
zeitwerk (~> 2.3)
|
||||||
addressable (2.7.0)
|
addressable (2.7.0)
|
||||||
public_suffix (>= 2.0.2, < 5.0)
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
ast (2.4.2)
|
|
||||||
autoprefixer-rails (10.2.4.0)
|
autoprefixer-rails (10.2.4.0)
|
||||||
execjs
|
execjs
|
||||||
bcrypt (3.1.16)
|
|
||||||
bindex (0.8.1)
|
bindex (0.8.1)
|
||||||
bootsnap (1.7.2)
|
bootsnap (1.7.2)
|
||||||
msgpack (~> 1.0)
|
msgpack (~> 1.0)
|
||||||
|
@ -80,128 +78,94 @@ GEM
|
||||||
regexp_parser (>= 1.5, < 3.0)
|
regexp_parser (>= 1.5, < 3.0)
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
childprocess (3.0.0)
|
childprocess (3.0.0)
|
||||||
concurrent-ruby (1.1.8)
|
concurrent-ruby (1.2.2)
|
||||||
crass (1.0.6)
|
crass (1.0.6)
|
||||||
diff-lcs (1.4.4)
|
date (3.3.3)
|
||||||
erubi (1.10.0)
|
erubi (1.12.0)
|
||||||
execjs (2.7.0)
|
execjs (2.7.0)
|
||||||
ffi (1.15.0)
|
ffi (1.15.0)
|
||||||
globalid (0.4.2)
|
globalid (1.2.1)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 6.1)
|
||||||
i18n (1.8.9)
|
i18n (1.14.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
jbuilder (2.11.2)
|
jbuilder (2.11.2)
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
jquery-rails (4.4.0)
|
|
||||||
rails-dom-testing (>= 1, < 3)
|
|
||||||
railties (>= 4.2.0)
|
|
||||||
thor (>= 0.14, < 2.0)
|
|
||||||
listen (3.4.1)
|
listen (3.4.1)
|
||||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||||
rb-inotify (~> 0.9, >= 0.9.10)
|
rb-inotify (~> 0.9, >= 0.9.10)
|
||||||
loofah (2.9.0)
|
loofah (2.21.3)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.12.0)
|
||||||
mail (2.7.1)
|
mail (2.8.1)
|
||||||
mini_mime (>= 0.1.1)
|
mini_mime (>= 0.1.1)
|
||||||
marcel (0.3.3)
|
net-imap
|
||||||
mimemagic (~> 0.3.2)
|
net-pop
|
||||||
|
net-smtp
|
||||||
|
marcel (1.0.2)
|
||||||
materialize-sass (1.0.0)
|
materialize-sass (1.0.0)
|
||||||
autoprefixer-rails (>= 6.0.3)
|
autoprefixer-rails (>= 6.0.3)
|
||||||
method_source (1.0.0)
|
method_source (1.0.0)
|
||||||
mimemagic (0.3.5)
|
mini_mime (1.1.5)
|
||||||
mini_mime (1.0.2)
|
mini_portile2 (2.8.4)
|
||||||
mini_portile2 (2.5.0)
|
minitest (5.20.0)
|
||||||
minitest (5.14.4)
|
|
||||||
msgpack (1.4.2)
|
msgpack (1.4.2)
|
||||||
nio4r (2.5.7)
|
net-imap (0.3.7)
|
||||||
nokogiri (1.11.2)
|
date
|
||||||
mini_portile2 (~> 2.5.0)
|
net-protocol
|
||||||
|
net-pop (0.1.2)
|
||||||
|
net-protocol
|
||||||
|
net-protocol (0.2.1)
|
||||||
|
timeout
|
||||||
|
net-smtp (0.4.0)
|
||||||
|
net-protocol
|
||||||
|
nio4r (2.5.9)
|
||||||
|
nokogiri (1.15.4)
|
||||||
|
mini_portile2 (~> 2.8.2)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
parallel (1.20.1)
|
|
||||||
parser (3.0.0.0)
|
|
||||||
ast (~> 2.4.1)
|
|
||||||
public_suffix (4.0.6)
|
public_suffix (4.0.6)
|
||||||
puma (5.2.2)
|
puma (5.2.2)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
racc (1.5.2)
|
racc (1.7.1)
|
||||||
rack (2.2.3)
|
rack (2.2.8)
|
||||||
rack-mini-profiler (2.3.1)
|
rack-mini-profiler (2.3.1)
|
||||||
rack (>= 1.2.0)
|
rack (>= 1.2.0)
|
||||||
rack-proxy (0.6.5)
|
rack-proxy (0.6.5)
|
||||||
rack
|
rack
|
||||||
rack-test (1.1.0)
|
rack-test (2.1.0)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.3)
|
||||||
rails (6.1.3)
|
rails (6.1.7.6)
|
||||||
actioncable (= 6.1.3)
|
actioncable (= 6.1.7.6)
|
||||||
actionmailbox (= 6.1.3)
|
actionmailbox (= 6.1.7.6)
|
||||||
actionmailer (= 6.1.3)
|
actionmailer (= 6.1.7.6)
|
||||||
actionpack (= 6.1.3)
|
actionpack (= 6.1.7.6)
|
||||||
actiontext (= 6.1.3)
|
actiontext (= 6.1.7.6)
|
||||||
actionview (= 6.1.3)
|
actionview (= 6.1.7.6)
|
||||||
activejob (= 6.1.3)
|
activejob (= 6.1.7.6)
|
||||||
activemodel (= 6.1.3)
|
activemodel (= 6.1.7.6)
|
||||||
activerecord (= 6.1.3)
|
activerecord (= 6.1.7.6)
|
||||||
activestorage (= 6.1.3)
|
activestorage (= 6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
activesupport (= 6.1.7.6)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 6.1.3)
|
railties (= 6.1.7.6)
|
||||||
sprockets-rails (>= 2.0.0)
|
sprockets-rails (>= 2.0.0)
|
||||||
rails-controller-testing (1.0.5)
|
rails-dom-testing (2.2.0)
|
||||||
actionpack (>= 5.0.1.rc1)
|
activesupport (>= 5.0.0)
|
||||||
actionview (>= 5.0.1.rc1)
|
minitest
|
||||||
activesupport (>= 5.0.1.rc1)
|
|
||||||
rails-dom-testing (2.0.3)
|
|
||||||
activesupport (>= 4.2.0)
|
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.3.0)
|
rails-html-sanitizer (1.6.0)
|
||||||
loofah (~> 2.3)
|
loofah (~> 2.21)
|
||||||
railties (6.1.3)
|
nokogiri (~> 1.14)
|
||||||
actionpack (= 6.1.3)
|
railties (6.1.7.6)
|
||||||
activesupport (= 6.1.3)
|
actionpack (= 6.1.7.6)
|
||||||
|
activesupport (= 6.1.7.6)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 0.8.7)
|
rake (>= 12.2)
|
||||||
thor (~> 1.0)
|
thor (~> 1.0)
|
||||||
rainbow (3.0.0)
|
rake (13.0.6)
|
||||||
rake (13.0.3)
|
|
||||||
rb-fsevent (0.10.4)
|
rb-fsevent (0.10.4)
|
||||||
rb-inotify (0.10.1)
|
rb-inotify (0.10.1)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
regexp_parser (2.1.1)
|
regexp_parser (2.1.1)
|
||||||
rexml (3.2.4)
|
|
||||||
rspec (3.10.0)
|
|
||||||
rspec-core (~> 3.10.0)
|
|
||||||
rspec-expectations (~> 3.10.0)
|
|
||||||
rspec-mocks (~> 3.10.0)
|
|
||||||
rspec-core (3.10.1)
|
|
||||||
rspec-support (~> 3.10.0)
|
|
||||||
rspec-expectations (3.10.1)
|
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
|
||||||
rspec-support (~> 3.10.0)
|
|
||||||
rspec-mocks (3.10.2)
|
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
|
||||||
rspec-support (~> 3.10.0)
|
|
||||||
rspec-rails (5.0.1)
|
|
||||||
actionpack (>= 5.2)
|
|
||||||
activesupport (>= 5.2)
|
|
||||||
railties (>= 5.2)
|
|
||||||
rspec-core (~> 3.10)
|
|
||||||
rspec-expectations (~> 3.10)
|
|
||||||
rspec-mocks (~> 3.10)
|
|
||||||
rspec-support (~> 3.10)
|
|
||||||
rspec-support (3.10.2)
|
|
||||||
rubocop (1.11.0)
|
|
||||||
parallel (~> 1.10)
|
|
||||||
parser (>= 3.0.0.0)
|
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
|
||||||
regexp_parser (>= 1.8, < 3.0)
|
|
||||||
rexml
|
|
||||||
rubocop-ast (>= 1.2.0, < 2.0)
|
|
||||||
ruby-progressbar (~> 1.7)
|
|
||||||
unicode-display_width (>= 1.4.0, < 3.0)
|
|
||||||
rubocop-ast (1.4.1)
|
|
||||||
parser (>= 2.7.1.5)
|
|
||||||
ruby-progressbar (1.11.0)
|
|
||||||
rubyzip (2.3.0)
|
rubyzip (2.3.0)
|
||||||
sass-rails (6.0.0)
|
sass-rails (6.0.0)
|
||||||
sassc-rails (~> 2.1, >= 2.1.1)
|
sassc-rails (~> 2.1, >= 2.1.1)
|
||||||
|
@ -218,22 +182,22 @@ GEM
|
||||||
rubyzip (>= 1.2.2)
|
rubyzip (>= 1.2.2)
|
||||||
semantic_range (3.0.0)
|
semantic_range (3.0.0)
|
||||||
spring (2.1.1)
|
spring (2.1.1)
|
||||||
sprockets (4.0.2)
|
sprockets (4.2.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
rack (> 1, < 3)
|
rack (>= 2.2.4, < 4)
|
||||||
sprockets-rails (3.2.2)
|
sprockets-rails (3.4.2)
|
||||||
actionpack (>= 4.0)
|
actionpack (>= 5.2)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 5.2)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
sqlite3 (1.4.2)
|
sqlite3 (1.4.2)
|
||||||
thor (1.1.0)
|
thor (1.2.2)
|
||||||
tilt (2.0.10)
|
tilt (2.0.10)
|
||||||
|
timeout (0.4.0)
|
||||||
turbolinks (5.2.1)
|
turbolinks (5.2.1)
|
||||||
turbolinks-source (~> 5.2)
|
turbolinks-source (~> 5.2)
|
||||||
turbolinks-source (5.2.0)
|
turbolinks-source (5.2.0)
|
||||||
tzinfo (2.0.4)
|
tzinfo (2.0.6)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
unicode-display_width (2.0.0)
|
|
||||||
web-console (4.1.0)
|
web-console (4.1.0)
|
||||||
actionview (>= 6.0.0)
|
actionview (>= 6.0.0)
|
||||||
activemodel (>= 6.0.0)
|
activemodel (>= 6.0.0)
|
||||||
|
@ -248,32 +212,26 @@ GEM
|
||||||
rack-proxy (>= 0.6.1)
|
rack-proxy (>= 0.6.1)
|
||||||
railties (>= 5.2)
|
railties (>= 5.2)
|
||||||
semantic_range (>= 2.3.0)
|
semantic_range (>= 2.3.0)
|
||||||
websocket-driver (0.7.3)
|
websocket-driver (0.7.6)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
zeitwerk (2.4.2)
|
zeitwerk (2.6.12)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
bcrypt (~> 3.1.7)
|
|
||||||
bootsnap (>= 1.4.4)
|
bootsnap (>= 1.4.4)
|
||||||
byebug
|
byebug
|
||||||
capybara (>= 3.26)
|
capybara (>= 3.26)
|
||||||
jbuilder (~> 2.7)
|
jbuilder (~> 2.7)
|
||||||
jquery-rails
|
|
||||||
listen (~> 3.3)
|
listen (~> 3.3)
|
||||||
materialize-sass (~> 1.0.0)
|
materialize-sass (~> 1.0.0)
|
||||||
puma (~> 5.0)
|
puma (~> 5.0)
|
||||||
rack-mini-profiler (~> 2.0)
|
rack-mini-profiler (~> 2.0)
|
||||||
rails (~> 6.1.3)
|
rails (~> 6.1.7.6)
|
||||||
rails-controller-testing
|
|
||||||
rspec
|
|
||||||
rspec-rails (>= 2.0.0.beta)
|
|
||||||
rubocop
|
|
||||||
sass-rails (>= 6)
|
sass-rails (>= 6)
|
||||||
selenium-webdriver
|
selenium-webdriver
|
||||||
spring
|
spring
|
||||||
|
|
4
Rakefile
4
Rakefile
|
@ -1,8 +1,6 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
# 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.
|
# 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
|
Rails.application.load_tasks
|
||||||
|
|
|
@ -1,6 +1,2 @@
|
||||||
@import "materialize";
|
@import "materialize";
|
||||||
@import "https://fonts.googleapis.com/icon?family=Material+Icons";
|
@import "https://fonts.googleapis.com/icon?family=Material+Icons";
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the sessions controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: https://sass-lang.com/
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the users controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: https://sass-lang.com/
|
|
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module ApplicationCable
|
module ApplicationCable
|
||||||
class Channel < ActionCable::Channel::Base
|
class Channel < ActionCable::Channel::Base
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module ApplicationCable
|
module ApplicationCable
|
||||||
class Connection < ActionCable::Connection::Base
|
class Connection < ActionCable::Connection::Base
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,28 +1,2 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Base for application controllers
|
|
||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
helper_method :current_user
|
|
||||||
helper_method :logged_in?
|
|
||||||
|
|
||||||
def current_user
|
|
||||||
User.find_by(id: session[:user_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def logged_in?
|
|
||||||
!current_user.nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def notices_from_errors(record)
|
|
||||||
errors = record.errors.messages.map do |attribute, messages|
|
|
||||||
messages.map { |message| "#{attribute} #{message}".capitalize }
|
|
||||||
end
|
|
||||||
errors.flatten
|
|
||||||
end
|
|
||||||
|
|
||||||
def ensure_admin
|
|
||||||
redirect_to '/welcome', notice: 'You are not allowed to perform this action' unless current_user&.admin?
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Authors controller
|
|
||||||
class AuthorsController < ApplicationController
|
|
||||||
before_action :ensure_admin
|
|
||||||
before_action :set_author, only: %i[edit update]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@authors = Author.all
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
@author = Author.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
redirect_to '/authors' if @author.update(author_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_author
|
|
||||||
@author = Author.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def author_params
|
|
||||||
params.require(:author).permit(:first_name, :last_name)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,47 +1,5 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Books controller
|
|
||||||
class BooksController < ApplicationController
|
class BooksController < ApplicationController
|
||||||
before_action :set_book, only: %i[show edit update add_to_cart]
|
|
||||||
before_action :ensure_admin, only: %i[edit update]
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
books = if current_user&.admin?
|
@books = Book.published.map { |book| BooksPresenter.new(book) }
|
||||||
Book.all
|
|
||||||
else
|
|
||||||
Book.published
|
|
||||||
end
|
|
||||||
@books = books.map { |book| BooksPresenter.new(book) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit; end
|
|
||||||
|
|
||||||
def update
|
|
||||||
redirect_to '/books' if @book.update(book_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_to_cart
|
|
||||||
@book = Book.find(params[:id])
|
|
||||||
return unless @book.quantity.positive?
|
|
||||||
|
|
||||||
current_user.books << @book
|
|
||||||
@book.decrement!(:quantity)
|
|
||||||
redirect_to '/books', notice: 'Book added to your cart'
|
|
||||||
end
|
|
||||||
|
|
||||||
def shopping_cart
|
|
||||||
@books = current_user.books.map { |book| BooksPresenter.new(book) }
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_book
|
|
||||||
@book = BooksPresenter.new(Book.find(params[:id]))
|
|
||||||
end
|
|
||||||
|
|
||||||
def book_params
|
|
||||||
result = params.require(:book).permit(:title, :price, :published)
|
|
||||||
result['price'] = result['price'].to_d * 100
|
|
||||||
result
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Sessions controller
|
|
||||||
class SessionsController < ApplicationController
|
|
||||||
def new; end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@user = User.find_by(email: params[:email])
|
|
||||||
problem = problem_with_login
|
|
||||||
if problem
|
|
||||||
redirect_to '/welcome', notice: problem
|
|
||||||
else
|
|
||||||
session[:user_id] = @user.id
|
|
||||||
redirect_to '/welcome'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def delete
|
|
||||||
session.delete(:user_id)
|
|
||||||
redirect_to '/welcome', notice: 'Logged out properly'
|
|
||||||
end
|
|
||||||
|
|
||||||
def welcome; end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def problem_with_login
|
|
||||||
if !@user
|
|
||||||
'Wrong email address'
|
|
||||||
elsif !@user.authenticate(params[:password])
|
|
||||||
'Wrong password'
|
|
||||||
elsif @user.blocked?
|
|
||||||
'You are blocked, please contact support'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,77 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Users controller
|
|
||||||
class UsersController < ApplicationController
|
|
||||||
before_action :ensure_admin, only: %i[destroy block]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@users = User.all
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
@user = User.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@user = User.create(params.require(:user).permit(:email, :password))
|
|
||||||
if @user.invalid?
|
|
||||||
redirect_to '/welcome', notice: notices_from_errors(@user)
|
|
||||||
else
|
|
||||||
session[:user_id] = @user.id
|
|
||||||
redirect_to '/welcome', notice: 'Account has been created'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def password_recovery_request
|
|
||||||
@user = User.where(email: params['email']).first
|
|
||||||
recovery_password = ('a'..'z').to_a.sample(8).join
|
|
||||||
@user.recovery_password = recovery_password
|
|
||||||
@user.save
|
|
||||||
UserMailer.with(user: @user, recovery_password: recovery_password).password_recovery.deliver_now
|
|
||||||
redirect_to '/welcome', notice: "Recovery email sent to #{params['email']}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def password_recovery_request_form; end
|
|
||||||
|
|
||||||
def recover_password_form
|
|
||||||
@recovery_password = params[:recovery_password]
|
|
||||||
@user_id = params[:id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def recover_password
|
|
||||||
@user = User.find(params[:user_id])
|
|
||||||
if recovery_password_proper?
|
|
||||||
set_new_password
|
|
||||||
else
|
|
||||||
redirect_to '/welcome', notice: 'Recovery link expired or invalid'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
User.destroy(params[:id])
|
|
||||||
redirect_to '/users'
|
|
||||||
end
|
|
||||||
|
|
||||||
def block
|
|
||||||
User.find(params[:id]).update(status: :blocked)
|
|
||||||
redirect_to '/users'
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def recovery_password_proper?
|
|
||||||
@user.recovery_password_digest &&
|
|
||||||
@user.authenticate_recovery_password(params[:recovery_password])
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_new_password
|
|
||||||
@user.password = params[:password]
|
|
||||||
@user.password_confirmation = params[:password_confirmation]
|
|
||||||
if @user.save
|
|
||||||
@user.update(recovery_password: nil)
|
|
||||||
redirect_to '/welcome', notice: 'Password changed'
|
|
||||||
else
|
|
||||||
redirect_to '/welcome', notice: 'Passwords don\'t match'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +1,2 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Application helper
|
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,12 +1,2 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Books helper
|
|
||||||
module BooksHelper
|
module BooksHelper
|
||||||
def cart_summary
|
|
||||||
number_to_currency(@books.map(&:price).reduce(:+))
|
|
||||||
end
|
|
||||||
|
|
||||||
def can_book_be_added?(book)
|
|
||||||
logged_in? && book.quantity.positive? && !current_user.books.exists?(book.id)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Sessions helper
|
|
||||||
module SessionsHelper
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Users helper
|
|
||||||
module UsersHelper
|
|
||||||
end
|
|
|
@ -4,8 +4,6 @@
|
||||||
// that code so it'll be compiled.
|
// that code so it'll be compiled.
|
||||||
|
|
||||||
//= require materialize
|
//= require materialize
|
||||||
//= require jquery
|
|
||||||
//= require jquery_ujs
|
|
||||||
|
|
||||||
import Rails from "@rails/ujs"
|
import Rails from "@rails/ujs"
|
||||||
import Turbolinks from "turbolinks"
|
import Turbolinks from "turbolinks"
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class ApplicationJob < ActiveJob::Base
|
class ApplicationJob < ActiveJob::Base
|
||||||
# Automatically retry jobs that encountered a deadlock
|
# Automatically retry jobs that encountered a deadlock
|
||||||
# retry_on ActiveRecord::Deadlocked
|
# retry_on ActiveRecord::Deadlocked
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class ApplicationMailer < ActionMailer::Base
|
class ApplicationMailer < ActionMailer::Base
|
||||||
default from: 'from@example.com'
|
default from: 'from@example.com'
|
||||||
layout 'mailer'
|
layout 'mailer'
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# User mailer
|
|
||||||
class UserMailer < ApplicationMailer
|
|
||||||
def password_recovery
|
|
||||||
@user = params[:user]
|
|
||||||
@recovery_password = params[:recovery_password]
|
|
||||||
@url = "http://localhost:18210/recover_password/#{@user.id}/#{@recovery_password}"
|
|
||||||
mail(to: @user.email, subject: 'Password recovery')
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,29 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Application record
|
|
||||||
class ApplicationRecord < ActiveRecord::Base
|
class ApplicationRecord < ActiveRecord::Base
|
||||||
self.abstract_class = true
|
self.abstract_class = true
|
||||||
def update(*args)
|
|
||||||
result = super(*args)
|
|
||||||
AuditRecord.create(model: self.class, action: 'update', params: to_json)
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
def save(*args)
|
|
||||||
result = super(*args)
|
|
||||||
AuditRecord.create(model: self.class, action: 'save', params: to_json)
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.create(*args)
|
|
||||||
result = super(*args)
|
|
||||||
AuditRecord.create(model: self.class, action: 'create', params: result.to_json)
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
def decrement!(*args)
|
|
||||||
result = super(*args)
|
|
||||||
AuditRecord.create(model: self.class, action: 'decrement!', params: to_json)
|
|
||||||
result
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class AuditRecord < ActiveRecord::Base
|
|
||||||
end
|
|
|
@ -1,6 +1,2 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Author < ApplicationRecord
|
class Author < ApplicationRecord
|
||||||
validates :first_name, presence: true
|
|
||||||
validates :last_name, presence: true
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Book < ApplicationRecord
|
class Book < ApplicationRecord
|
||||||
has_and_belongs_to_many :authors
|
has_and_belongs_to_many :authors
|
||||||
|
|
||||||
scope :published, -> { where(published: true) }
|
scope :published, -> { where(published: true) }
|
||||||
validates :title, presence: true
|
|
||||||
validates :price, presence: true
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class User < ApplicationRecord
|
|
||||||
has_and_belongs_to_many :books
|
|
||||||
|
|
||||||
has_secure_password
|
|
||||||
has_secure_password :recovery_password, validations: false
|
|
||||||
enum role: %i[customer admin], _default: :customer
|
|
||||||
enum status: %i[ready blocked], _default: :ready
|
|
||||||
|
|
||||||
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
|
|
||||||
validates :role, presence: true
|
|
||||||
validates :status, presence: true
|
|
||||||
validates :password, {
|
|
||||||
presence: true,
|
|
||||||
length: { minimum: 8 },
|
|
||||||
if: -> { new_record? || !password.nil? }
|
|
||||||
}
|
|
||||||
end
|
|
|
@ -1,15 +1,8 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Books presenter
|
|
||||||
class BooksPresenter < SimpleDelegator
|
class BooksPresenter < SimpleDelegator
|
||||||
include ActiveSupport::NumberHelper
|
include ActiveSupport::NumberHelper
|
||||||
|
|
||||||
def price
|
def price
|
||||||
super / 100
|
number_to_currency(super / 100)
|
||||||
end
|
|
||||||
|
|
||||||
def price_with_currency
|
|
||||||
number_to_currency(price)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def authors
|
def authors
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<h4>Edit author</h4>
|
|
||||||
<%= form_for @author do |f|%>
|
|
||||||
<%= f.label :first_name %>
|
|
||||||
<%= f.text_field :first_name %>
|
|
||||||
<%= f.label :last_name %>
|
|
||||||
<%= f.text_field :last_name %>
|
|
||||||
<%= f.submit 'Save changes', class: 'btn' %>
|
|
||||||
<%end%>
|
|
||||||
</div>
|
|
|
@ -1,13 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<% @authors.each do |author| %>
|
|
||||||
<div class='row'>
|
|
||||||
<div class='col s11'>
|
|
||||||
<%= author.first_name %> <%= author.last_name %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='col s1'>
|
|
||||||
<%= link_to 'Edit', edit_author_path(author), class: "btn" %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
|
@ -1,16 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<h4>Edit book</h4>
|
|
||||||
<%= form_for @book do |f|%>
|
|
||||||
<%= f.label :title %>
|
|
||||||
<%= f.text_field :title %>
|
|
||||||
<%= f.label :price %>
|
|
||||||
<%= f.number_field :price, step: 0.01 %>
|
|
||||||
<label>
|
|
||||||
<div>
|
|
||||||
<%= f.check_box :published, class: 'filled-in' %>
|
|
||||||
<span>published</span>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
<%= f.submit 'Save changes', class: 'btn' %>
|
|
||||||
<%end%>
|
|
||||||
</div>
|
|
|
@ -1,42 +1,17 @@
|
||||||
<div class='container'>
|
<div class='container'>
|
||||||
<div class='row'>
|
|
||||||
<h6 class='col s2'>Title</h6>
|
|
||||||
<h6 class='col s3'>Authors</h6>
|
|
||||||
<h6 class='col s1'>Price</h6>
|
|
||||||
<h6 class='col s3'>Quantity</h6>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<% @books.each do |book| %>
|
<% @books.each do |book| %>
|
||||||
<div class='row'>
|
<div class='row'>
|
||||||
<div class='col s2'>
|
<div class='col s4'>
|
||||||
<%= book.title %>
|
Title: <%= book.title %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='col s3'>
|
<div class='col s4'>
|
||||||
<%= book.authors %>
|
Price: <%= book.price %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='col s1'>
|
<div class='col s4'>
|
||||||
<%= book.price_with_currency %>
|
Authors: <%= book.authors %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='col s1'>
|
|
||||||
<%= book.quantity %>
|
|
||||||
</div>
|
|
||||||
<div class='col s2'>
|
|
||||||
<% if can_book_be_added?(book) %>
|
|
||||||
<%= link_to 'Add', "book/#{book.id}/add_to_cart", method: :post, class: "btn" %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<% if current_user&.admin? %>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= book.published ? 'published' : 'unpublished' %>
|
|
||||||
</div>
|
|
||||||
<div class='col s1'>
|
|
||||||
<%= link_to 'Edit', edit_book_path(book), class: "btn" %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<div class='row'>
|
|
||||||
<h6 class='col s2'>Title</h6>
|
|
||||||
<h6 class='col s3'>Authors</h6>
|
|
||||||
<h6 class='col s1'>Price</h6>
|
|
||||||
</div>
|
|
||||||
<% @books.each do |book| %>
|
|
||||||
<div class='row'>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= book.title %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='col s3'>
|
|
||||||
<%= book.authors %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='col s1'>
|
|
||||||
<%= book.price_with_currency %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<div class='row'>
|
|
||||||
<div class='col s5'><strong>Summary</strong></div>
|
|
||||||
<div class='col s1'><%= cart_summary %></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -2,53 +2,15 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Book store</title>
|
<title>Book store</title>
|
||||||
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<%= csrf_meta_tags %>
|
<%= csrf_meta_tags %>
|
||||||
<%= csp_meta_tag %>
|
<%= csp_meta_tag %>
|
||||||
|
|
||||||
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||||
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
||||||
<%= javascript_include_tag 'rails-ujs' %>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class='container'>
|
|
||||||
<div class='card-panel'>
|
|
||||||
<div class='row'>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= link_to 'Home', '/welcome', method: :get%>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= link_to 'Books', '/books', method: :get%>
|
|
||||||
</div>
|
|
||||||
<% if current_user&.admin? %>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= link_to 'Authors', '/authors', method: :get%>
|
|
||||||
</div>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= link_to 'Users', '/users', method: :get%>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<% if logged_in? %>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= link_to 'Shopping cart', '/shopping_cart', method: :get%>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<% flash.each do |type, notice| %>
|
|
||||||
<div class='card-panel teal lighten-5'>
|
|
||||||
<% if notice.is_a? String %>
|
|
||||||
<%= notice %>
|
|
||||||
<% else %>
|
|
||||||
<% notice.each do |msg| %>
|
|
||||||
<div><%= msg %></div>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<%= yield %>
|
<%= yield %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<h4>Login</h4>
|
|
||||||
<%= form_tag '/login' do %>
|
|
||||||
<%= label_tag :email%>
|
|
||||||
<%= text_field_tag :email %>
|
|
||||||
<%= label_tag :password%>
|
|
||||||
<%= password_field_tag :password%>
|
|
||||||
<%= submit_tag "Login", class: 'btn' %>
|
|
||||||
<%end%>
|
|
||||||
<%= link_to "Password recovery", '/password_recovery_request', method: :get %>
|
|
||||||
</div>
|
|
|
@ -1,13 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<h4>Welcome</h4>
|
|
||||||
<div class='row'>
|
|
||||||
<% if logged_in? %>
|
|
||||||
<p>You are logged in, <%= current_user.email %></p>
|
|
||||||
<%= link_to 'Logout', '/logout', method: :get, class: 'btn' %>
|
|
||||||
<% else %>
|
|
||||||
<p>You are not logged in</p>
|
|
||||||
<%= link_to 'Login', '/login', method: :get, class: 'btn' %>
|
|
||||||
<%= link_to 'Sign Up', '/users/new', method: :get, class: 'btn' %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
Please click the link to recover your password: <%= @url %>
|
|
|
@ -1,21 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<% @users.each do |user| %>
|
|
||||||
<div class='row'>
|
|
||||||
<div class='col s3'>
|
|
||||||
<%= user.email %>
|
|
||||||
</div>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= user.role %>
|
|
||||||
</div>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= user.status %>
|
|
||||||
</div>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= link_to 'Delete', user, method: :delete, class: "btn" %>
|
|
||||||
</div>
|
|
||||||
<div class='col s2'>
|
|
||||||
<%= link_to 'Block', "/user/#{user.id}/block", method: :post, class: "btn" %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<h4>Sign Up</h4>
|
|
||||||
<%= form_for @user do |f|%>
|
|
||||||
<%= f.label :email%>
|
|
||||||
<%= f.text_field :email%>
|
|
||||||
<%= f.label :password%>
|
|
||||||
<%= f.password_field :password%>
|
|
||||||
<%= f.submit 'Sign up', class: 'btn' %>
|
|
||||||
<%end%>
|
|
||||||
</div>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<h4>Password recovery</h4>
|
|
||||||
Provide an email to password recovery
|
|
||||||
<%= form_with url: "/password_recovery_request", method: :post do |f| %>
|
|
||||||
<%= f.label :email%><br>
|
|
||||||
<%= f.text_field :email %>
|
|
||||||
<%= f.submit 'Send email', class: 'btn' %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
|
@ -1,13 +0,0 @@
|
||||||
<div class='container'>
|
|
||||||
<h4>Provide new password</h4>
|
|
||||||
|
|
||||||
<%= form_with url: '/recover_password', method: :post do |f| %>
|
|
||||||
<%= f.label :password%>
|
|
||||||
<%= f.password_field :password %>
|
|
||||||
<%= f.label :password_confirmation%>
|
|
||||||
<%= f.password_field :password_confirmation %>
|
|
||||||
<%= f.hidden_field :recovery_password, :value => @recovery_password %>
|
|
||||||
<%= f.hidden_field :user_id, :value => @user_id %>
|
|
||||||
<%= f.submit 'Change password', class: 'btn' %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
46
bin/bundle
46
bin/bundle
|
@ -8,46 +8,46 @@
|
||||||
# this file is here to facilitate running it.
|
# this file is here to facilitate running it.
|
||||||
#
|
#
|
||||||
|
|
||||||
require 'rubygems'
|
require "rubygems"
|
||||||
|
|
||||||
m = Module.new do
|
m = Module.new do
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def invoked_as_script?
|
def invoked_as_script?
|
||||||
File.expand_path($PROGRAM_NAME) == File.expand_path(__FILE__)
|
File.expand_path($0) == File.expand_path(__FILE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
def env_var_version
|
def env_var_version
|
||||||
ENV['BUNDLER_VERSION']
|
ENV["BUNDLER_VERSION"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def cli_arg_version
|
def cli_arg_version
|
||||||
return unless invoked_as_script? # don't want to hijack other binstubs
|
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
|
bundler_version = nil
|
||||||
update_index = nil
|
update_index = nil
|
||||||
ARGV.each_with_index do |a, i|
|
ARGV.each_with_index do |a, i|
|
||||||
bundler_version = a if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
|
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
|
||||||
|
bundler_version = a
|
||||||
|
end
|
||||||
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
|
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
|
||||||
|
bundler_version = $1
|
||||||
bundler_version = Regexp.last_match(1)
|
|
||||||
update_index = i
|
update_index = i
|
||||||
end
|
end
|
||||||
bundler_version
|
bundler_version
|
||||||
end
|
end
|
||||||
|
|
||||||
def gemfile
|
def gemfile
|
||||||
gemfile = ENV['BUNDLE_GEMFILE']
|
gemfile = ENV["BUNDLE_GEMFILE"]
|
||||||
return gemfile if gemfile && !gemfile.empty?
|
return gemfile if gemfile && !gemfile.empty?
|
||||||
|
|
||||||
File.expand_path('../Gemfile', __dir__)
|
File.expand_path("../../Gemfile", __FILE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
def lockfile
|
def lockfile
|
||||||
lockfile =
|
lockfile =
|
||||||
case File.basename(gemfile)
|
case File.basename(gemfile)
|
||||||
when 'gems.rb' then gemfile.sub(/\.rb$/, gemfile)
|
when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
|
||||||
else "#{gemfile}.lock"
|
else "#{gemfile}.lock"
|
||||||
end
|
end
|
||||||
File.expand_path(lockfile)
|
File.expand_path(lockfile)
|
||||||
|
@ -55,17 +55,15 @@ m = Module.new do
|
||||||
|
|
||||||
def lockfile_version
|
def lockfile_version
|
||||||
return unless File.file?(lockfile)
|
return unless File.file?(lockfile)
|
||||||
|
|
||||||
lockfile_contents = File.read(lockfile)
|
lockfile_contents = File.read(lockfile)
|
||||||
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
|
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
|
||||||
|
|
||||||
Regexp.last_match(1)
|
Regexp.last_match(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def bundler_version
|
def bundler_version
|
||||||
@bundler_version ||=
|
@bundler_version ||=
|
||||||
env_var_version || cli_arg_version ||
|
env_var_version || cli_arg_version ||
|
||||||
lockfile_version
|
lockfile_version
|
||||||
end
|
end
|
||||||
|
|
||||||
def bundler_requirement
|
def bundler_requirement
|
||||||
|
@ -75,32 +73,28 @@ m = Module.new do
|
||||||
|
|
||||||
requirement = bundler_gem_version.approximate_recommendation
|
requirement = bundler_gem_version.approximate_recommendation
|
||||||
|
|
||||||
return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new('2.7.0')
|
return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
|
||||||
|
|
||||||
requirement += '.a' if bundler_gem_version.prerelease?
|
requirement += ".a" if bundler_gem_version.prerelease?
|
||||||
|
|
||||||
requirement
|
requirement
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_bundler!
|
def load_bundler!
|
||||||
ENV['BUNDLE_GEMFILE'] ||= gemfile
|
ENV["BUNDLE_GEMFILE"] ||= gemfile
|
||||||
|
|
||||||
activate_bundler
|
activate_bundler
|
||||||
end
|
end
|
||||||
|
|
||||||
def activate_bundler
|
def activate_bundler
|
||||||
gem_error = activation_error_handling do
|
gem_error = activation_error_handling do
|
||||||
gem 'bundler', bundler_requirement
|
gem "bundler", bundler_requirement
|
||||||
end
|
end
|
||||||
return if gem_error.nil?
|
return if gem_error.nil?
|
||||||
|
|
||||||
require_error = activation_error_handling do
|
require_error = activation_error_handling do
|
||||||
require 'bundler/version'
|
require "bundler/version"
|
||||||
end
|
end
|
||||||
if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
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}'`"
|
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
|
exit 42
|
||||||
end
|
end
|
||||||
|
@ -115,4 +109,6 @@ end
|
||||||
|
|
||||||
m.load_bundler!
|
m.load_bundler!
|
||||||
|
|
||||||
load Gem.bin_path('bundler', 'bundle') if m.invoked_as_script?
|
if m.invoked_as_script?
|
||||||
|
load Gem.bin_path("bundler", "bundle")
|
||||||
|
end
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# frozen_string_literal: true
|
load File.expand_path("spring", __dir__)
|
||||||
|
|
||||||
load File.expand_path('spring', __dir__)
|
|
||||||
APP_PATH = File.expand_path('../config/application', __dir__)
|
APP_PATH = File.expand_path('../config/application', __dir__)
|
||||||
require_relative '../config/boot'
|
require_relative "../config/boot"
|
||||||
require 'rails/commands'
|
require "rails/commands"
|
||||||
|
|
8
bin/rake
8
bin/rake
|
@ -1,7 +1,5 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# frozen_string_literal: true
|
load File.expand_path("spring", __dir__)
|
||||||
|
require_relative "../config/boot"
|
||||||
load File.expand_path('spring', __dir__)
|
require "rake"
|
||||||
require_relative '../config/boot'
|
|
||||||
require 'rake'
|
|
||||||
Rake.application.run
|
Rake.application.run
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# frozen_string_literal: true
|
require "fileutils"
|
||||||
|
|
||||||
require 'fileutils'
|
|
||||||
|
|
||||||
# path to your application root.
|
# path to your application root.
|
||||||
APP_ROOT = File.expand_path('..', __dir__)
|
APP_ROOT = File.expand_path('..', __dir__)
|
||||||
|
|
14
bin/spring
14
bin/spring
|
@ -1,15 +1,13 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# frozen_string_literal: true
|
if !defined?(Spring) && [nil, "development", "test"].include?(ENV["RAILS_ENV"])
|
||||||
|
gem "bundler"
|
||||||
if !defined?(Spring) && [nil, 'development', 'test'].include?(ENV['RAILS_ENV'])
|
require "bundler"
|
||||||
gem 'bundler'
|
|
||||||
require 'bundler'
|
|
||||||
|
|
||||||
# Load Spring without loading other gems in the Gemfile, for speed.
|
# Load Spring without loading other gems in the Gemfile, for speed.
|
||||||
Bundler.locked_gems&.specs&.find { |spec| spec.name == 'spring' }&.tap do |spring|
|
Bundler.locked_gems&.specs&.find { |spec| spec.name == "spring" }&.tap do |spring|
|
||||||
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
|
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
|
||||||
gem 'spring', spring.version
|
gem "spring", spring.version
|
||||||
require 'spring/binstub'
|
require "spring/binstub"
|
||||||
rescue Gem::LoadError
|
rescue Gem::LoadError
|
||||||
# Ignore when Spring is not installed.
|
# Ignore when Spring is not installed.
|
||||||
end
|
end
|
||||||
|
|
19
bin/webpack
19
bin/webpack
|
@ -1,19 +1,18 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
ENV['RAILS_ENV'] ||= ENV['RACK_ENV'] || 'development'
|
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
|
||||||
ENV['NODE_ENV'] ||= 'development'
|
ENV["NODE_ENV"] ||= "development"
|
||||||
|
|
||||||
require 'pathname'
|
require "pathname"
|
||||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||||
Pathname.new(__FILE__).realpath)
|
Pathname.new(__FILE__).realpath)
|
||||||
|
|
||||||
require 'bundler/setup'
|
require "bundler/setup"
|
||||||
|
|
||||||
require 'webpacker'
|
require "webpacker"
|
||||||
require 'webpacker/webpack_runner'
|
require "webpacker/webpack_runner"
|
||||||
|
|
||||||
APP_ROOT = File.expand_path('..', __dir__)
|
APP_ROOT = File.expand_path("..", __dir__)
|
||||||
Dir.chdir(APP_ROOT) do
|
Dir.chdir(APP_ROOT) do
|
||||||
Webpacker::WebpackRunner.run(ARGV)
|
Webpacker::WebpackRunner.run(ARGV)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
ENV['RAILS_ENV'] ||= ENV['RACK_ENV'] || 'development'
|
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
|
||||||
ENV['NODE_ENV'] ||= 'development'
|
ENV["NODE_ENV"] ||= "development"
|
||||||
|
|
||||||
require 'pathname'
|
require "pathname"
|
||||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||||
Pathname.new(__FILE__).realpath)
|
Pathname.new(__FILE__).realpath)
|
||||||
|
|
||||||
require 'bundler/setup'
|
require "bundler/setup"
|
||||||
|
|
||||||
require 'webpacker'
|
require "webpacker"
|
||||||
require 'webpacker/dev_server_runner'
|
require "webpacker/dev_server_runner"
|
||||||
|
|
||||||
APP_ROOT = File.expand_path('..', __dir__)
|
APP_ROOT = File.expand_path("..", __dir__)
|
||||||
Dir.chdir(APP_ROOT) do
|
Dir.chdir(APP_ROOT) do
|
||||||
Webpacker::DevServerRunner.run(ARGV)
|
Webpacker::DevServerRunner.run(ARGV)
|
||||||
end
|
end
|
||||||
|
|
16
bin/yarn
16
bin/yarn
|
@ -1,19 +1,17 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
APP_ROOT = File.expand_path('..', __dir__)
|
APP_ROOT = File.expand_path('..', __dir__)
|
||||||
Dir.chdir(APP_ROOT) do
|
Dir.chdir(APP_ROOT) do
|
||||||
yarn = ENV['PATH'].split(File::PATH_SEPARATOR)
|
yarn = ENV["PATH"].split(File::PATH_SEPARATOR).
|
||||||
.reject { |dir| File.expand_path(dir) == __dir__ }
|
select { |dir| File.expand_path(dir) != __dir__ }.
|
||||||
.product(['yarn', 'yarn.cmd', 'yarn.ps1'])
|
product(["yarn", "yarn.cmd", "yarn.ps1"]).
|
||||||
.map { |dir, file| File.expand_path(file, dir) }
|
map { |dir, file| File.expand_path(file, dir) }.
|
||||||
.find { |file| File.executable?(file) }
|
find { |file| File.executable?(file) }
|
||||||
|
|
||||||
if yarn
|
if yarn
|
||||||
exec yarn, *ARGV
|
exec yarn, *ARGV
|
||||||
else
|
else
|
||||||
warn 'Yarn executable was not detected in the system.'
|
$stderr.puts "Yarn executable was not detected in the system."
|
||||||
warn 'Download Yarn at https://yarnpkg.com/en/docs/install'
|
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# This file is used by Rack-based servers to start the application.
|
# This file is used by Rack-based servers to start the application.
|
||||||
|
|
||||||
require_relative 'config/environment'
|
require_relative "config/environment"
|
||||||
|
|
||||||
run Rails.application
|
run Rails.application
|
||||||
Rails.application.load_server
|
Rails.application.load_server
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
# frozen_string_literal: true
|
require_relative "boot"
|
||||||
|
|
||||||
require_relative 'boot'
|
require "rails/all"
|
||||||
|
|
||||||
require 'rails/all'
|
|
||||||
|
|
||||||
# Require the gems listed in Gemfile, including any gems
|
# Require the gems listed in Gemfile, including any gems
|
||||||
# you've limited to :test, :development, or :production.
|
# you've limited to :test, :development, or :production.
|
||||||
Bundler.require(*Rails.groups)
|
Bundler.require(*Rails.groups)
|
||||||
|
|
||||||
# App
|
|
||||||
module App
|
module App
|
||||||
class Application < Rails::Application
|
class Application < Rails::Application
|
||||||
# Initialize configuration defaults for originally generated Rails version.
|
# Initialize configuration defaults for originally generated Rails version.
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||||
|
|
||||||
require 'bundler/setup' # Set up gems listed in the Gemfile.
|
require "bundler/setup" # Set up gems listed in the Gemfile.
|
||||||
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
|
require "bootsnap/setup" # Speed up boot time by caching expensive operations.
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Load the Rails application.
|
# Load the Rails application.
|
||||||
require_relative 'application'
|
require_relative "application"
|
||||||
|
|
||||||
# Initialize the Rails application.
|
# Initialize the Rails application.
|
||||||
Rails.application.initialize!
|
Rails.application.initialize!
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# frozen_string_literal: true
|
require "active_support/core_ext/integer/time"
|
||||||
|
|
||||||
require 'active_support/core_ext/integer/time'
|
|
||||||
|
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
# Settings specified here will take precedence over those in config/application.rb.
|
# Settings specified here will take precedence over those in config/application.rb.
|
||||||
|
@ -58,8 +56,7 @@ Rails.application.configure do
|
||||||
# Debug mode disables concatenation and preprocessing of assets.
|
# Debug mode disables concatenation and preprocessing of assets.
|
||||||
# This option may cause significant delays in view rendering with a large
|
# This option may cause significant delays in view rendering with a large
|
||||||
# number of complex assets.
|
# number of complex assets.
|
||||||
config.assets.debug = false
|
config.assets.debug = true
|
||||||
config.assets.check_precompiled_asset = false
|
|
||||||
|
|
||||||
# Suppress logger output for asset requests.
|
# Suppress logger output for asset requests.
|
||||||
config.assets.quiet = true
|
config.assets.quiet = true
|
||||||
|
@ -76,4 +73,6 @@ Rails.application.configure do
|
||||||
|
|
||||||
# Uncomment if you wish to allow Action Cable access from any origin.
|
# Uncomment if you wish to allow Action Cable access from any origin.
|
||||||
# config.action_cable.disable_request_forgery_protection = true
|
# config.action_cable.disable_request_forgery_protection = true
|
||||||
|
#
|
||||||
|
config.web_console.permissions = '192.168.0.0/16'
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# frozen_string_literal: true
|
require "active_support/core_ext/integer/time"
|
||||||
|
|
||||||
require 'active_support/core_ext/integer/time'
|
|
||||||
|
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
# Settings specified here will take precedence over those in config/application.rb.
|
# Settings specified here will take precedence over those in config/application.rb.
|
||||||
|
@ -55,7 +53,7 @@ Rails.application.configure do
|
||||||
config.log_level = :info
|
config.log_level = :info
|
||||||
|
|
||||||
# Prepend all log lines with the following tags.
|
# Prepend all log lines with the following tags.
|
||||||
config.log_tags = [:request_id]
|
config.log_tags = [ :request_id ]
|
||||||
|
|
||||||
# Use a different cache store in production.
|
# Use a different cache store in production.
|
||||||
# config.cache_store = :mem_cache_store
|
# config.cache_store = :mem_cache_store
|
||||||
|
@ -90,8 +88,8 @@ Rails.application.configure do
|
||||||
# require "syslog/logger"
|
# require "syslog/logger"
|
||||||
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
|
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
|
||||||
|
|
||||||
if ENV['RAILS_LOG_TO_STDOUT'].present?
|
if ENV["RAILS_LOG_TO_STDOUT"].present?
|
||||||
logger = ActiveSupport::Logger.new($stdout)
|
logger = ActiveSupport::Logger.new(STDOUT)
|
||||||
logger.formatter = config.log_formatter
|
logger.formatter = config.log_formatter
|
||||||
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# frozen_string_literal: true
|
require "active_support/core_ext/integer/time"
|
||||||
|
|
||||||
require 'active_support/core_ext/integer/time'
|
|
||||||
|
|
||||||
# The test environment is used exclusively to run your application's
|
# The test environment is used exclusively to run your application's
|
||||||
# test suite. You never need to work with it otherwise. Remember that
|
# test suite. You never need to work with it otherwise. Remember that
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# ActiveSupport::Reloader.to_prepare do
|
# ActiveSupport::Reloader.to_prepare do
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# Version of your assets, change this if you want to expire all your assets.
|
# Version of your assets, change this if you want to expire all your assets.
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
||||||
|
@ -7,4 +5,4 @@
|
||||||
|
|
||||||
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
|
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
|
||||||
# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
|
# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
|
||||||
Rails.backtrace_cleaner.remove_silencers! if ENV['BACKTRACE']
|
Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"]
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# Define an application-wide content security policy
|
# Define an application-wide content security policy
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# Specify a serializer for the signed and encrypted cookie jars.
|
# Specify a serializer for the signed and encrypted cookie jars.
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# Configure sensitive parameters which will be filtered from the log file.
|
# Configure sensitive parameters which will be filtered from the log file.
|
||||||
Rails.application.config.filter_parameters += %i[
|
Rails.application.config.filter_parameters += [
|
||||||
passw secret token _key crypt salt certificate otp ssn
|
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# Add new inflection rules using the following format. Inflections
|
# Add new inflection rules using the following format. Inflections
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# Add new mime types for use in respond_to blocks:
|
# Add new mime types for use in respond_to blocks:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
# Define an application-wide HTTP permissions policy. For further
|
# Define an application-wide HTTP permissions policy. For further
|
||||||
# information see https://developers.google.com/web/updates/2018/06/feature-policy
|
# information see https://developers.google.com/web/updates/2018/06/feature-policy
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# This file contains settings for ActionController::ParamsWrapper which
|
# This file contains settings for ActionController::ParamsWrapper which
|
||||||
|
|
|
@ -1,30 +1,28 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Puma can serve each request in a thread from an internal thread pool.
|
# Puma can serve each request in a thread from an internal thread pool.
|
||||||
# The `threads` method setting takes two numbers: a minimum and maximum.
|
# The `threads` method setting takes two numbers: a minimum and maximum.
|
||||||
# Any libraries that use thread pools should be configured to match
|
# Any libraries that use thread pools should be configured to match
|
||||||
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
||||||
# and maximum; this matches the default thread size of Active Record.
|
# and maximum; this matches the default thread size of Active Record.
|
||||||
#
|
#
|
||||||
max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 5)
|
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
|
||||||
min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
|
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
|
||||||
threads min_threads_count, max_threads_count
|
threads min_threads_count, max_threads_count
|
||||||
|
|
||||||
# Specifies the `worker_timeout` threshold that Puma will use to wait before
|
# Specifies the `worker_timeout` threshold that Puma will use to wait before
|
||||||
# terminating a worker in development environments.
|
# terminating a worker in development environments.
|
||||||
#
|
#
|
||||||
worker_timeout 3600 if ENV.fetch('RAILS_ENV', 'development') == 'development'
|
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
|
||||||
|
|
||||||
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
||||||
#
|
#
|
||||||
port ENV.fetch('PORT', 3000)
|
port ENV.fetch("PORT") { 3000 }
|
||||||
|
|
||||||
# Specifies the `environment` that Puma will run in.
|
# Specifies the `environment` that Puma will run in.
|
||||||
#
|
#
|
||||||
environment ENV.fetch('RAILS_ENV', 'development')
|
environment ENV.fetch("RAILS_ENV") { "development" }
|
||||||
|
|
||||||
# Specifies the `pidfile` that Puma will use.
|
# Specifies the `pidfile` that Puma will use.
|
||||||
pidfile ENV.fetch('PIDFILE', 'tmp/pids/server.pid')
|
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
|
||||||
|
|
||||||
# Specifies the number of `workers` to boot in clustered mode.
|
# Specifies the number of `workers` to boot in clustered mode.
|
||||||
# Workers are forked web server processes. If using threads and workers together
|
# Workers are forked web server processes. If using threads and workers together
|
||||||
|
|
|
@ -1,19 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
resources :users
|
|
||||||
get 'login', to: 'sessions#new'
|
|
||||||
get 'logout', to: 'sessions#delete'
|
|
||||||
post 'login', to: 'sessions#create'
|
|
||||||
get 'welcome', to: 'sessions#welcome'
|
|
||||||
get 'password_recovery_request', to: 'users#password_recovery_request_form'
|
|
||||||
post 'password_recovery_request', to: 'users#password_recovery_request'
|
|
||||||
get 'recover_password/:id/:recovery_password', to: 'users#recover_password_form'
|
|
||||||
post 'recover_password', to: 'users#recover_password'
|
|
||||||
post 'user/:id/block', to: 'users#block'
|
|
||||||
post 'book/:id/add_to_cart', to: 'books#add_to_cart'
|
|
||||||
get 'shopping_cart', to: 'books#shopping_cart'
|
|
||||||
|
|
||||||
resources :books
|
resources :books
|
||||||
resources :authors
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
Spring.watch(
|
Spring.watch(
|
||||||
'.ruby-version',
|
".ruby-version",
|
||||||
'.rbenv-vars',
|
".rbenv-vars",
|
||||||
'tmp/restart.txt',
|
"tmp/restart.txt",
|
||||||
'tmp/caching-dev.txt'
|
"tmp/caching-dev.txt"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Create authors
|
|
||||||
class CreateAuthors < ActiveRecord::Migration[6.1]
|
class CreateAuthors < ActiveRecord::Migration[6.1]
|
||||||
def change
|
def change
|
||||||
create_table :authors do |t|
|
create_table :authors do |t|
|
||||||
|
@ -10,6 +7,6 @@ class CreateAuthors < ActiveRecord::Migration[6.1]
|
||||||
t.timestamps
|
t.timestamps
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index :authors, %i[first_name last_name]
|
add_index :authors, [ :first_name, :last_name ]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Create books
|
|
||||||
class CreateBooks < ActiveRecord::Migration[6.1]
|
class CreateBooks < ActiveRecord::Migration[6.1]
|
||||||
def change
|
def change
|
||||||
create_table :books do |t|
|
create_table :books do |t|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Create association table between authors and books
|
|
||||||
class CreateAuthorsBooks < ActiveRecord::Migration[6.1]
|
class CreateAuthorsBooks < ActiveRecord::Migration[6.1]
|
||||||
def change
|
def change
|
||||||
create_table :authors_books do |t|
|
create_table :authors_books do |t|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Create users
|
|
||||||
class CreateUsers < ActiveRecord::Migration[6.1]
|
|
||||||
def change
|
|
||||||
create_table :users do |t|
|
|
||||||
t.string :username
|
|
||||||
t.string :password_digest
|
|
||||||
|
|
||||||
t.timestamps
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,7 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class ChangeUsernameToEmail < ActiveRecord::Migration[6.1]
|
|
||||||
def change
|
|
||||||
rename_column :users, :username, :email
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,7 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class AddPasswordRecoveryCodeToUsers < ActiveRecord::Migration[6.1]
|
|
||||||
def change
|
|
||||||
add_column :users, :password_recovery_code, :string
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,7 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class ChangePasswordRecoveryCodeToRecoveryPasswordDigest < ActiveRecord::Migration[6.1]
|
|
||||||
def change
|
|
||||||
rename_column :users, :password_recovery_code, :recovery_password_digest
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,7 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class AddRoleToUsers < ActiveRecord::Migration[6.1]
|
|
||||||
def change
|
|
||||||
add_column :users, :role, :integer
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,7 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class AddStatusToUsers < ActiveRecord::Migration[6.1]
|
|
||||||
def change
|
|
||||||
add_column :users, :status, :integer
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,13 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class CreateAuditRecords < ActiveRecord::Migration[6.1]
|
|
||||||
def change
|
|
||||||
create_table :audit_records do |t|
|
|
||||||
t.string :model
|
|
||||||
t.string :action
|
|
||||||
t.string :params
|
|
||||||
|
|
||||||
t.timestamps
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,7 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class AddQuantityToBooks < ActiveRecord::Migration[6.1]
|
|
||||||
def change
|
|
||||||
add_column :books, :quantity, :integer
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,12 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class CreateBooksUsers < ActiveRecord::Migration[6.1]
|
|
||||||
def change
|
|
||||||
create_table :books_users do |t|
|
|
||||||
t.belongs_to :book
|
|
||||||
t.belongs_to :user
|
|
||||||
|
|
||||||
t.timestamps
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
72
db/schema.rb
generated
72
db/schema.rb
generated
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# This file is auto-generated from the current state of the database. Instead
|
# This file is auto-generated from the current state of the database. Instead
|
||||||
# of editing this file, please use the migrations feature of Active Record to
|
# of editing this file, please use the migrations feature of Active Record to
|
||||||
# incrementally modify your database, and then regenerate this schema definition.
|
# incrementally modify your database, and then regenerate this schema definition.
|
||||||
|
@ -12,58 +10,32 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20_210_322_002_803) do
|
ActiveRecord::Schema.define(version: 2021_03_19_142059) do
|
||||||
create_table 'audit_records', force: :cascade do |t|
|
|
||||||
t.string 'model'
|
create_table "authors", force: :cascade do |t|
|
||||||
t.string 'action'
|
t.string "first_name"
|
||||||
t.string 'params'
|
t.string "last_name"
|
||||||
t.datetime 'created_at', precision: 6, null: false
|
t.datetime "created_at", precision: 6, null: false
|
||||||
t.datetime 'updated_at', precision: 6, null: false
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
|
t.index ["first_name", "last_name"], name: "index_authors_on_first_name_and_last_name"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table 'authors', force: :cascade do |t|
|
create_table "authors_books", force: :cascade do |t|
|
||||||
t.string 'first_name'
|
t.integer "book_id"
|
||||||
t.string 'last_name'
|
t.integer "author_id"
|
||||||
t.datetime 'created_at', precision: 6, null: false
|
t.datetime "created_at", precision: 6, null: false
|
||||||
t.datetime 'updated_at', precision: 6, null: false
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
t.index %w[first_name last_name], name: 'index_authors_on_first_name_and_last_name'
|
t.index ["author_id"], name: "index_authors_books_on_author_id"
|
||||||
|
t.index ["book_id"], name: "index_authors_books_on_book_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table 'authors_books', force: :cascade do |t|
|
create_table "books", force: :cascade do |t|
|
||||||
t.integer 'book_id'
|
t.string "title"
|
||||||
t.integer 'author_id'
|
t.decimal "price", precision: 10, scale: 2
|
||||||
t.datetime 'created_at', precision: 6, null: false
|
t.boolean "published"
|
||||||
t.datetime 'updated_at', precision: 6, null: false
|
t.datetime "created_at", precision: 6, null: false
|
||||||
t.index ['author_id'], name: 'index_authors_books_on_author_id'
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
t.index ['book_id'], name: 'index_authors_books_on_book_id'
|
t.index ["published"], name: "index_books_on_published"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table 'books', force: :cascade do |t|
|
|
||||||
t.string 'title'
|
|
||||||
t.decimal 'price', precision: 10, scale: 2
|
|
||||||
t.boolean 'published'
|
|
||||||
t.datetime 'created_at', precision: 6, null: false
|
|
||||||
t.datetime 'updated_at', precision: 6, null: false
|
|
||||||
t.integer 'quantity'
|
|
||||||
t.index ['published'], name: 'index_books_on_published'
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table 'books_users', force: :cascade do |t|
|
|
||||||
t.integer 'book_id'
|
|
||||||
t.integer 'user_id'
|
|
||||||
t.datetime 'created_at', precision: 6, null: false
|
|
||||||
t.datetime 'updated_at', precision: 6, null: false
|
|
||||||
t.index ['book_id'], name: 'index_books_users_on_book_id'
|
|
||||||
t.index ['user_id'], name: 'index_books_users_on_user_id'
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table 'users', force: :cascade do |t|
|
|
||||||
t.string 'email'
|
|
||||||
t.string 'password_digest'
|
|
||||||
t.datetime 'created_at', precision: 6, null: false
|
|
||||||
t.datetime 'updated_at', precision: 6, null: false
|
|
||||||
t.string 'recovery_password_digest'
|
|
||||||
t.integer 'role'
|
|
||||||
t.integer 'status'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
117
db/seeds.rb
117
db/seeds.rb
|
@ -1,74 +1,51 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
books = Book.create([
|
books = Book.create([
|
||||||
{
|
{
|
||||||
title: 'Journey to the Center of the Earth',
|
title: 'Journey to the Center of the Earth',
|
||||||
price: 10_900,
|
price: 10900,
|
||||||
published: true,
|
published: true
|
||||||
quantity: 100
|
},
|
||||||
},
|
{
|
||||||
{
|
title: 'From the Earth to the Moon',
|
||||||
title: 'From the Earth to the Moon',
|
price: 6300,
|
||||||
price: 6300,
|
published: false
|
||||||
published: false,
|
},
|
||||||
quantity: 0
|
{
|
||||||
},
|
title: 'Imaginary trip',
|
||||||
{
|
price: 3600,
|
||||||
title: 'Imaginary trip',
|
published: true
|
||||||
price: 3600,
|
},
|
||||||
published: true,
|
])
|
||||||
quantity: 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Winnie the Pooh',
|
|
||||||
price: 3700,
|
|
||||||
published: true,
|
|
||||||
quantity: 5
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
authors = Author.create([
|
authors = Author.create([
|
||||||
{
|
{
|
||||||
first_name: 'Jules',
|
first_name: 'Jules',
|
||||||
last_name: 'Verne'
|
last_name: 'Verne'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
first_name: 'Dick',
|
first_name: 'Dick',
|
||||||
last_name: 'Pick'
|
last_name: 'Pick',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
first_name: 'Rick',
|
first_name: 'Rick',
|
||||||
last_name: 'Pickle'
|
last_name: 'Pickle'
|
||||||
},
|
},
|
||||||
{
|
])
|
||||||
first_name: 'Alan',
|
|
||||||
last_name: 'Milne'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
books.first.authors << authors.first
|
BookAuthor.create([
|
||||||
books.second.authors << authors.first
|
{
|
||||||
books.third.authors << authors.second
|
book: books.first,
|
||||||
books.third.authors << authors.third
|
author: authors.first
|
||||||
books.fourth.authors << authors.fourth
|
},
|
||||||
|
{
|
||||||
User.create([
|
book: books[1],
|
||||||
{
|
author: authors.first
|
||||||
email: 'abc@o2.pl',
|
},
|
||||||
password: 'aaaaaaaa',
|
{
|
||||||
role: :admin,
|
book: books[2],
|
||||||
status: :ready
|
author: authors[1]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: 'abcd@o2.pl',
|
book: books[2],
|
||||||
password: 'aaaaaaaa',
|
author: authors[2]
|
||||||
role: :customer,
|
},
|
||||||
status: :ready
|
])
|
||||||
},
|
|
||||||
{
|
|
||||||
email: 'abcde@o2.pl',
|
|
||||||
password: 'aaaaaaaa',
|
|
||||||
role: :customer,
|
|
||||||
status: :ready
|
|
||||||
}
|
|
||||||
])
|
|
|
@ -12,7 +12,7 @@ services:
|
||||||
env_file:
|
env_file:
|
||||||
- docker/.env
|
- docker/.env
|
||||||
webpack_dev_server:
|
webpack_dev_server:
|
||||||
image: bookstore_bookstore
|
image: bookstore-bookstore
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/app:delegated
|
- ./:/app:delegated
|
||||||
- bundle_volume:/usr/local/bundle
|
- bundle_volume:/usr/local/bundle
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
yarn install
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
<!-- This file lives in public/404.html -->
|
<!-- This file lives in public/404.html -->
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<div>
|
<div>
|
||||||
<h4>The page you were looking for doesn't exist.</h4>
|
<h1>The page you were looking for doesn't exist.</h1>
|
||||||
<p>You may have mistyped the address or the page may have moved.</p>
|
<p>You may have mistyped the address or the page may have moved.</p>
|
||||||
</div>
|
</div>
|
||||||
<p>If you are the application owner check the logs for more information.</p>
|
<p>If you are the application owner check the logs for more information.</p>
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
<!-- This file lives in public/422.html -->
|
<!-- This file lives in public/422.html -->
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<div>
|
<div>
|
||||||
<h4>The change you wanted was rejected.</h4>
|
<h1>The change you wanted was rejected.</h1>
|
||||||
<p>Maybe you tried to change something you didn't have access to.</p>
|
<p>Maybe you tried to change something you didn't have access to.</p>
|
||||||
</div>
|
</div>
|
||||||
<p>If you are the application owner check the logs for more information.</p>
|
<p>If you are the application owner check the logs for more information.</p>
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
<!-- This file lives in public/500.html -->
|
<!-- This file lives in public/500.html -->
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<div>
|
<div>
|
||||||
<h4>We're sorry, but something went wrong.</h4>
|
<h1>We're sorry, but something went wrong.</h1>
|
||||||
</div>
|
</div>
|
||||||
<p>If you are the application owner check the logs for more information.</p>
|
<p>If you are the application owner check the logs for more information.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe ApplicationController do
|
|
||||||
describe 'current_user' do
|
|
||||||
before(:all) do
|
|
||||||
User.create(email: 'test2@example.com', password: 'abcde')
|
|
||||||
end
|
|
||||||
context 'when a user is logged in' do
|
|
||||||
it 'returns the user' do
|
|
||||||
# TODO
|
|
||||||
# expect(current_user.email).to eql('test2@example.com')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'logged_in?' do
|
|
||||||
# TODO
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,32 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe SessionsController do
|
|
||||||
describe 'get new' do
|
|
||||||
subject { get 'new' }
|
|
||||||
it 'renders the sessions/new template' do
|
|
||||||
expect(subject).to render_template('sessions/new')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'get create' do
|
|
||||||
# TODO: test session status
|
|
||||||
subject { get 'create' }
|
|
||||||
it 'redirects to /welcome' do
|
|
||||||
expect(subject).to redirect_to('/welcome')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'get delete' do
|
|
||||||
# TODO: test session status
|
|
||||||
subject { get 'delete' }
|
|
||||||
it 'redirects to /welcome' do
|
|
||||||
expect(subject).to redirect_to('/welcome')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'get welcome' do
|
|
||||||
subject { get 'welcome' }
|
|
||||||
it 'renders the sessions/welcome template' do
|
|
||||||
expect(subject).to render_template('sessions/welcome')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,127 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe UsersController do
|
|
||||||
before(:all) do # TODO: turn it into cleanup after each test
|
|
||||||
User.destroy_all
|
|
||||||
end
|
|
||||||
let(:user1) do
|
|
||||||
User.create(
|
|
||||||
email: 'test1@example.com',
|
|
||||||
password: 'abcdefgh',
|
|
||||||
recovery_password: 'recovery password',
|
|
||||||
role: :admin
|
|
||||||
)
|
|
||||||
end
|
|
||||||
describe 'get index' do
|
|
||||||
subject { get :index }
|
|
||||||
it 'renders the users/index template' do
|
|
||||||
expect(subject).to render_template('users/index')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'get new' do
|
|
||||||
subject { get :new }
|
|
||||||
it 'renders the users/new template' do
|
|
||||||
expect(subject).to render_template('users/new')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'get create' do
|
|
||||||
subject do
|
|
||||||
get :create, params: { user: { email: 'test2@example.com', password: 'abcdefgh' } }
|
|
||||||
end
|
|
||||||
it 'creates a user' do
|
|
||||||
subject
|
|
||||||
expect(User.where(email: 'test2@example.com').size).to eql(1)
|
|
||||||
end
|
|
||||||
it 'redirects to /welcome' do
|
|
||||||
subject
|
|
||||||
expect(subject).to redirect_to('/welcome')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'get password_recovery_request_form' do
|
|
||||||
subject { get :password_recovery_request_form }
|
|
||||||
it 'renders the users/password_recovery_request_form template' do
|
|
||||||
expect(subject).to render_template('users/password_recovery_request_form')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'post password_recovery_request' do
|
|
||||||
subject do
|
|
||||||
get :password_recovery_request, params: { email: user1.email }
|
|
||||||
end
|
|
||||||
it 'sends the proper recovery email' do
|
|
||||||
srand(10)
|
|
||||||
subject
|
|
||||||
email_text = ActionMailer::Base.deliveries.last.body.raw_source
|
|
||||||
expect(email_text).to match("recover_password/#{user1.id}/jeravuxl")
|
|
||||||
end
|
|
||||||
it 'sends a recovery email to the proper email' do
|
|
||||||
subject
|
|
||||||
expect(ActionMailer::Base.deliveries.last.to).to eql([user1.email])
|
|
||||||
end
|
|
||||||
it 'flashes a notice' do
|
|
||||||
subject
|
|
||||||
expect(subject.request.flash[:notice]).to match("Recovery email sent to #{user1.email}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'get recover_password_form' do
|
|
||||||
subject do
|
|
||||||
get :recover_password_form, params: { id: user1.id, recovery_password: 'recovery password' }
|
|
||||||
end
|
|
||||||
it 'renders proper form' do
|
|
||||||
subject
|
|
||||||
expect(subject).to render_template('users/recover_password_form')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'post recover_password' do
|
|
||||||
context 'when passwords match and recovery password is proper' do
|
|
||||||
subject do
|
|
||||||
post :recover_password, params: {
|
|
||||||
user_id: user1.id,
|
|
||||||
recovery_password: 'recovery password',
|
|
||||||
password: 'new password',
|
|
||||||
password_confirmation: 'new password'
|
|
||||||
}
|
|
||||||
end
|
|
||||||
it 'flashes a notice about success' do
|
|
||||||
subject
|
|
||||||
expect(subject.request.flash[:notice]).to match('Password changed')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
context 'when recovery password is inproper' do
|
|
||||||
subject do
|
|
||||||
post :recover_password, params: {
|
|
||||||
user_id: user1.id,
|
|
||||||
recovery_password: 'improper recovery password',
|
|
||||||
password: 'new password',
|
|
||||||
password_confirmation: 'new password'
|
|
||||||
}
|
|
||||||
end
|
|
||||||
it 'flashes a notice about failure' do
|
|
||||||
subject
|
|
||||||
expect(subject.request.flash[:notice]).to match('Recovery link expired or invalid')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
context 'when passwords match and recovery password is improper' do
|
|
||||||
subject do
|
|
||||||
post :recover_password, params: {
|
|
||||||
user_id: user1.id,
|
|
||||||
recovery_password: 'recovery password',
|
|
||||||
password: 'new password',
|
|
||||||
password_confirmation: 'bad password'
|
|
||||||
}
|
|
||||||
end
|
|
||||||
it 'flashes a notice about failure' do
|
|
||||||
subject
|
|
||||||
expect(subject.request.flash[:notice]).to match('Passwords don\'t match')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
describe 'delete destroy' do
|
|
||||||
context 'when admin is logged in' do
|
|
||||||
it 'deletes the user' do
|
|
||||||
# TODO
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Preview all emails at http://localhost:3000/rails/mailers/user
|
|
||||||
class UserMailerPreview < ActionMailer::Preview
|
|
||||||
end
|
|
|
@ -1,7 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe UserMailer, type: :mailer do
|
|
||||||
# TODO
|
|
||||||
end
|
|
|
@ -1,66 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
|
||||||
require 'spec_helper'
|
|
||||||
ENV['RAILS_ENV'] ||= 'test'
|
|
||||||
require File.expand_path('../config/environment', __dir__)
|
|
||||||
# Prevent database truncation if the environment is production
|
|
||||||
abort('The Rails environment is running in production mode!') if Rails.env.production?
|
|
||||||
require 'rspec/rails'
|
|
||||||
# Add additional requires below this line. Rails is not loaded until this point!
|
|
||||||
|
|
||||||
# Requires supporting ruby files with custom matchers and macros, etc, in
|
|
||||||
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
|
|
||||||
# run as spec files by default. This means that files in spec/support that end
|
|
||||||
# in _spec.rb will both be required and run as specs, causing the specs to be
|
|
||||||
# run twice. It is recommended that you do not name files matching this glob to
|
|
||||||
# end with _spec.rb. You can configure this pattern with the --pattern
|
|
||||||
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
|
|
||||||
#
|
|
||||||
# The following line is provided for convenience purposes. It has the downside
|
|
||||||
# of increasing the boot-up time by auto-requiring all files in the support
|
|
||||||
# directory. Alternatively, in the individual `*_spec.rb` files, manually
|
|
||||||
# require only the support files necessary.
|
|
||||||
#
|
|
||||||
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
|
|
||||||
|
|
||||||
# Checks for pending migrations and applies them before tests are run.
|
|
||||||
# If you are not using ActiveRecord, you can remove these lines.
|
|
||||||
begin
|
|
||||||
ActiveRecord::Migration.maintain_test_schema!
|
|
||||||
rescue ActiveRecord::PendingMigrationError => e
|
|
||||||
puts e.to_s.strip
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
RSpec.configure do |config|
|
|
||||||
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
|
||||||
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
|
||||||
|
|
||||||
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
|
||||||
# examples within a transaction, remove the following line or assign false
|
|
||||||
# instead of true.
|
|
||||||
config.use_transactional_fixtures = true
|
|
||||||
|
|
||||||
# You can uncomment this line to turn off ActiveRecord support entirely.
|
|
||||||
# config.use_active_record = false
|
|
||||||
|
|
||||||
# RSpec Rails can automatically mix in different behaviours to your tests
|
|
||||||
# based on their file location, for example enabling you to call `get` and
|
|
||||||
# `post` in specs under `spec/controllers`.
|
|
||||||
#
|
|
||||||
# You can disable this behaviour by removing the line below, and instead
|
|
||||||
# explicitly tag your specs with their type, e.g.:
|
|
||||||
#
|
|
||||||
# RSpec.describe UsersController, type: :controller do
|
|
||||||
# # ...
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# The different available types are documented in the features, such as in
|
|
||||||
# https://relishapp.com/rspec/rspec-rails/docs
|
|
||||||
config.infer_spec_type_from_file_location!
|
|
||||||
|
|
||||||
# Filter lines from Rails gems in backtraces.
|
|
||||||
config.filter_rails_from_backtrace!
|
|
||||||
# arbitrary gems may also be filtered via:
|
|
||||||
# config.filter_gems_from_backtrace("gem name")
|
|
||||||
end
|
|
|
@ -1,96 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# This file was generated by the `rails generate rspec:install` command. Conventionally, all
|
|
||||||
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
|
||||||
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
|
||||||
# this file to always be loaded, without a need to explicitly require it in any
|
|
||||||
# files.
|
|
||||||
#
|
|
||||||
# Given that it is always loaded, you are encouraged to keep this file as
|
|
||||||
# light-weight as possible. Requiring heavyweight dependencies from this file
|
|
||||||
# will add to the boot time of your test suite on EVERY test run, even for an
|
|
||||||
# individual file that may not need all of that loaded. Instead, consider making
|
|
||||||
# a separate helper file that requires the additional dependencies and performs
|
|
||||||
# the additional setup, and require it from the spec files that actually need
|
|
||||||
# it.
|
|
||||||
#
|
|
||||||
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
|
||||||
RSpec.configure do |config|
|
|
||||||
# rspec-expectations config goes here. You can use an alternate
|
|
||||||
# assertion/expectation library such as wrong or the stdlib/minitest
|
|
||||||
# assertions if you prefer.
|
|
||||||
config.expect_with :rspec do |expectations|
|
|
||||||
# This option will default to `true` in RSpec 4. It makes the `description`
|
|
||||||
# and `failure_message` of custom matchers include text for helper methods
|
|
||||||
# defined using `chain`, e.g.:
|
|
||||||
# be_bigger_than(2).and_smaller_than(4).description
|
|
||||||
# # => "be bigger than 2 and smaller than 4"
|
|
||||||
# ...rather than:
|
|
||||||
# # => "be bigger than 2"
|
|
||||||
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
|
||||||
end
|
|
||||||
|
|
||||||
# rspec-mocks config goes here. You can use an alternate test double
|
|
||||||
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
|
||||||
config.mock_with :rspec do |mocks|
|
|
||||||
# Prevents you from mocking or stubbing a method that does not exist on
|
|
||||||
# a real object. This is generally recommended, and will default to
|
|
||||||
# `true` in RSpec 4.
|
|
||||||
mocks.verify_partial_doubles = true
|
|
||||||
end
|
|
||||||
|
|
||||||
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will
|
|
||||||
# have no way to turn it off -- the option exists only for backwards
|
|
||||||
# compatibility in RSpec 3). It causes shared context metadata to be
|
|
||||||
# inherited by the metadata hash of host groups and examples, rather than
|
|
||||||
# triggering implicit auto-inclusion in groups with matching metadata.
|
|
||||||
config.shared_context_metadata_behavior = :apply_to_host_groups
|
|
||||||
|
|
||||||
# The settings below are suggested to provide a good initial experience
|
|
||||||
# with RSpec, but feel free to customize to your heart's content.
|
|
||||||
# # This allows you to limit a spec run to individual examples or groups
|
|
||||||
# # you care about by tagging them with `:focus` metadata. When nothing
|
|
||||||
# # is tagged with `:focus`, all examples get run. RSpec also provides
|
|
||||||
# # aliases for `it`, `describe`, and `context` that include `:focus`
|
|
||||||
# # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
|
||||||
# config.filter_run_when_matching :focus
|
|
||||||
#
|
|
||||||
# # Allows RSpec to persist some state between runs in order to support
|
|
||||||
# # the `--only-failures` and `--next-failure` CLI options. We recommend
|
|
||||||
# # you configure your source control system to ignore this file.
|
|
||||||
# config.example_status_persistence_file_path = "spec/examples.txt"
|
|
||||||
#
|
|
||||||
# # Limits the available syntax to the non-monkey patched syntax that is
|
|
||||||
# # recommended. For more details, see:
|
|
||||||
# # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
|
||||||
# # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
|
||||||
# # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
|
||||||
# config.disable_monkey_patching!
|
|
||||||
#
|
|
||||||
# # Many RSpec users commonly either run the entire suite or an individual
|
|
||||||
# # file, and it's useful to allow more verbose output when running an
|
|
||||||
# # individual spec file.
|
|
||||||
# if config.files_to_run.one?
|
|
||||||
# # Use the documentation formatter for detailed output,
|
|
||||||
# # unless a formatter has already been configured
|
|
||||||
# # (e.g. via a command-line flag).
|
|
||||||
# config.default_formatter = "doc"
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# # Print the 10 slowest examples and example groups at the
|
|
||||||
# # end of the spec run, to help surface which specs are running
|
|
||||||
# # particularly slow.
|
|
||||||
# config.profile_examples = 10
|
|
||||||
#
|
|
||||||
# # Run specs in random order to surface order dependencies. If you find an
|
|
||||||
# # order dependency and want to debug it, you can fix the order by providing
|
|
||||||
# # the seed, which is printed after each run.
|
|
||||||
# # --seed 1234
|
|
||||||
# config.order = :random
|
|
||||||
#
|
|
||||||
# # Seed global randomization in this process using the `--seed` CLI option.
|
|
||||||
# # Setting this allows you to use `--seed` to deterministically reproduce
|
|
||||||
# # test failures related to randomization by passing the same `--seed` value
|
|
||||||
# # as the one that triggered the failure.
|
|
||||||
# Kernel.srand config.seed
|
|
||||||
end
|
|
5
test/application_system_test_case.rb
Normal file
5
test/application_system_test_case.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
||||||
|
driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
|
||||||
|
end
|
11
test/channels/application_cable/connection_test.rb
Normal file
11
test/channels/application_cable/connection_test.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase
|
||||||
|
# test "connects with cookies" do
|
||||||
|
# cookies.signed[:user_id] = 42
|
||||||
|
#
|
||||||
|
# connect
|
||||||
|
#
|
||||||
|
# assert_equal connection.user_id, "42"
|
||||||
|
# end
|
||||||
|
end
|
0
test/controllers/.keep
Normal file
0
test/controllers/.keep
Normal file
7
test/controllers/books_controller_test.rb
Normal file
7
test/controllers/books_controller_test.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class BooksControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
# test "the truth" do
|
||||||
|
# assert true
|
||||||
|
# end
|
||||||
|
end
|
11
test/fixtures/authors.yml
vendored
Normal file
11
test/fixtures/authors.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||||
|
|
||||||
|
# This model initially had no columns defined. If you add columns to the
|
||||||
|
# model remove the '{}' from the fixture names and add the columns immediately
|
||||||
|
# below each fixture, per the syntax in the comments below
|
||||||
|
#
|
||||||
|
one: {}
|
||||||
|
# column: value
|
||||||
|
#
|
||||||
|
two: {}
|
||||||
|
# column: value
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue