rails_app_generator 0.0.3 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.vscode/settings.json +3 -0
  4. data/CHANGELOG.md +21 -0
  5. data/README.md +9 -1
  6. data/exe/rails_app_generator +51 -0
  7. data/lib/rails_app_generator/add_on.rb +74 -0
  8. data/lib/rails_app_generator/addons/annotate.rb +15 -0
  9. data/lib/rails_app_generator/addons/continuous_integration.rb +14 -0
  10. data/lib/rails_app_generator/addons/devise.rb +50 -0
  11. data/lib/rails_app_generator/addons/docker.rb +14 -0
  12. data/lib/rails_app_generator/addons/docker_compose.rb +13 -0
  13. data/lib/rails_app_generator/addons/dotenv.rb +13 -0
  14. data/lib/rails_app_generator/addons/factory_bot.rb +19 -0
  15. data/lib/rails_app_generator/addons/foreman.rb +15 -0
  16. data/lib/rails_app_generator/addons/generators.rb +31 -0
  17. data/lib/rails_app_generator/addons/high_voltage.rb +15 -0
  18. data/lib/rails_app_generator/addons/inline_svg.rb +11 -0
  19. data/lib/rails_app_generator/addons/irbrc.rb +13 -0
  20. data/lib/rails_app_generator/addons/lograge.rb +13 -0
  21. data/lib/rails_app_generator/addons/pundit.rb +16 -0
  22. data/lib/rails_app_generator/addons/rspec.rb +17 -0
  23. data/lib/rails_app_generator/addons/rubocop.rb +13 -0
  24. data/lib/rails_app_generator/addons/scaffold.rb +15 -0
  25. data/lib/rails_app_generator/addons/services.rb +13 -0
  26. data/lib/rails_app_generator/addons/sidekiq.rb +18 -0
  27. data/lib/rails_app_generator/addons/stimulus.rb +15 -0
  28. data/lib/rails_app_generator/addons/stimulus_components.rb +33 -0
  29. data/lib/rails_app_generator/addons/tailwind.rb +22 -0
  30. data/lib/rails_app_generator/addons/views.rb +21 -0
  31. data/lib/rails_app_generator/app_builder.rb +2 -2
  32. data/lib/rails_app_generator/app_generator.rb +147 -103
  33. data/lib/rails_app_generator/context.rb +75 -0
  34. data/lib/rails_app_generator/dependencies.rb +34 -0
  35. data/lib/rails_app_generator/notes/a1.txt +86 -0
  36. data/lib/rails_app_generator/notes/a2.txt +87 -0
  37. data/lib/rails_app_generator/notes/kw01-b.txt +86 -0
  38. data/lib/rails_app_generator/notes/kw01.txt +91 -0
  39. data/lib/rails_app_generator/options/base_map_option.rb +10 -0
  40. data/lib/rails_app_generator/options/build_option.rb +4 -2
  41. data/lib/rails_app_generator/options/map_option_boolean_flag.rb +3 -3
  42. data/lib/rails_app_generator/options/{map_option_pass_through.rb → map_option_ignore.rb} +3 -3
  43. data/lib/rails_app_generator/options/map_option_string.rb +14 -0
  44. data/lib/rails_app_generator/options/{build_options.rb → options_builder.rb} +13 -2
  45. data/lib/rails_app_generator/options/rails_options.rb +77 -0
  46. data/lib/rails_app_generator/starter.rb +55 -39
  47. data/lib/rails_app_generator/version.rb +1 -1
  48. data/lib/rails_app_generator.rb +10 -3
  49. data/package-lock.json +2 -2
  50. data/package.json +1 -1
  51. data/templates/addons/annotate/auto_annotate_models.rake +60 -0
  52. data/templates/addons/continuous_integration/.github/workflows/build.yml.erb +49 -0
  53. data/templates/addons/devise/app/views/devise/confirmations/new.html.erb +24 -0
  54. data/templates/addons/devise/app/views/devise/passwords/edit.html.erb +34 -0
  55. data/templates/addons/devise/app/views/devise/passwords/new.html.erb +23 -0
  56. data/templates/addons/devise/app/views/devise/registrations/edit.html.erb +62 -0
  57. data/templates/addons/devise/app/views/devise/registrations/new.html.erb +45 -0
  58. data/templates/addons/devise/app/views/devise/sessions/new.html.erb +33 -0
  59. data/templates/addons/devise/app/views/devise/shared/_error_messages.html.erb +15 -0
  60. data/templates/addons/devise/app/views/devise/shared/_form_wrap.html.erb +5 -0
  61. data/templates/addons/devise/app/views/devise/shared/_links.html.erb +25 -0
  62. data/templates/addons/devise/app/views/devise/unlocks/new.html.erb +22 -0
  63. data/templates/addons/docker/.dockerignore.erb +51 -0
  64. data/templates/addons/docker/Dockerfile.erb +45 -0
  65. data/templates/addons/docker_compose/docker-compose.yml.erb +21 -0
  66. data/templates/addons/dotenv/.env.development.erb +3 -0
  67. data/templates/addons/foreman/.foreman.erb +1 -0
  68. data/templates/addons/foreman/Procfile.dev.erb +7 -0
  69. data/templates/addons/foreman/Procfile.erb +4 -0
  70. data/templates/addons/generators/lib/generators/rails/navigation/USAGE +6 -0
  71. data/templates/addons/generators/lib/generators/rails/navigation/navigation_generator.rb +16 -0
  72. data/templates/addons/generators/lib/generators/rails/scaffold_controller_generator.rb +12 -0
  73. data/templates/addons/high_voltage/config/initializers/high_voltage.rb +6 -0
  74. data/templates/addons/irbrc/.irbrc.erb +13 -0
  75. data/templates/addons/lograge/config/initializers/lograge.rb +5 -0
  76. data/templates/addons/pundit/app/controllers/authorized_controller.rb.erb +10 -0
  77. data/templates/addons/pundit/app/policies/application_policy.rb +57 -0
  78. data/templates/addons/rspec/spec/rails_helper.rb +26 -0
  79. data/templates/addons/rspec/spec/spec_helper.rb +61 -0
  80. data/templates/addons/rubocop/.rubocop.yml.erb +37 -0
  81. data/templates/addons/scaffold/lib/templates/erb/scaffold/_form.html.erb +39 -0
  82. data/templates/addons/scaffold/lib/templates/erb/scaffold/edit.html.erb +7 -0
  83. data/templates/addons/scaffold/lib/templates/erb/scaffold/index.html.erb +34 -0
  84. data/templates/addons/scaffold/lib/templates/erb/scaffold/new.html.erb +7 -0
  85. data/templates/addons/scaffold/lib/templates/erb/scaffold/show.html.erb +18 -0
  86. data/templates/addons/services/app/services/application_service.rb +15 -0
  87. data/templates/app_x/controllers/authorized_controller.rb.erb +10 -0
  88. data/templates/app_x/controllers/errors_controller.rb.erb +24 -0
  89. data/templates/app_x/javascript/images/checkmark.svg +1 -0
  90. data/templates/app_x/javascript/images/logo.svg +1 -0
  91. data/templates/app_x/javascript/stylesheets/components.scss +206 -0
  92. data/templates/app_x/views/errors/internal_error.html.erb +14 -0
  93. data/templates/app_x/views/errors/not_found.html.erb +14 -0
  94. data/templates/app_x/views/errors/unacceptable.html.erb +14 -0
  95. data/templates/app_x/views/layouts/application.html.erb.tt +30 -0
  96. data/templates/app_x/views/pages/home.html.erb.tt +20 -0
  97. data/templates/app_x/views/shared/_flashes.html.erb.tt +12 -0
  98. data/templates/app_x/views/shared/_footer.html.erb.tt +21 -0
  99. data/templates/app_x/views/shared/_navbar.html.erb.tt +55 -0
  100. data/templates/app_x/workers/application_worker.rb +5 -0
  101. metadata +175 -5
@@ -0,0 +1,62 @@
1
+ <% content_for :devise_form do %>
2
+ <h2 class="pt-4 mb-8 text-4xl font-bold heading">Edit <%= resource_name.to_s.humanize %></h2>
3
+
4
+ <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
5
+
6
+ <%= render "devise/shared/error_messages", resource: resource %>
7
+
8
+ <div class="input-group">
9
+ <%= f.label :name, class:"label" %>
10
+ <%= f.text_field :name, class:"input" %>
11
+ </div>
12
+
13
+ <div class="input-group">
14
+ <%= f.label :email, class:"label" %>
15
+ <%= f.email_field :email, autocomplete: "email", class:"input" %>
16
+ </div>
17
+
18
+ <div class="input-group">
19
+ <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
20
+ <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
21
+ <% end %>
22
+ </div>
23
+
24
+ <div class="input-group">
25
+ <%= f.label :password, class:"label" %>
26
+ <%= f.password_field :password, autocomplete: "new-password", class:"input" %>
27
+ <p class="pt-1 text-sm italic text-grey-dark"> <% if @minimum_password_length %>
28
+ <%= @minimum_password_length %> characters minimum <% end %> (leave blank if you don't want to change it) </p>
29
+
30
+ </div>
31
+
32
+ <div class="input-group">
33
+ <%= f.label :password_confirmation, class: "label" %>
34
+ <%= f.password_field :password_confirmation, autocomplete: "new-password", class: "input" %>
35
+ </div>
36
+
37
+ <div class="input-group">
38
+ <%= f.label :current_password, class: "label" %>
39
+ <%= f.password_field :current_password, autocomplete: "current-password", class: "input" %>
40
+ <p class="pt-2 text-sm italic text-grey-dark">(we need your current password to confirm your changes)</p>
41
+ </div>
42
+
43
+ <div class="input-group">
44
+ <%= f.submit "Update", class: "btn btn-default" %>
45
+ </div>
46
+ <% end %>
47
+
48
+ <hr class="mt-6 mb-3 border" />
49
+
50
+ <h3 class="mb-4 text-xl font-bold heading">Cancel my account</h3>
51
+
52
+ <div class="flex items-center justify-between">
53
+ <div class="flex-1">
54
+ <p class="py-4">Unhappy?</p>
55
+ </div>
56
+
57
+ <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-red" %>
58
+ </div>
59
+
60
+ <% end %>
61
+
62
+ <%= render 'devise/shared/form_wrap' %>
@@ -0,0 +1,45 @@
1
+ <% content_for :devise_form do %>
2
+
3
+ <h2 class="pt-4 mb-8 text-4xl font-bold heading">Sign up</h2>
4
+
5
+ <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
6
+ <%= render "devise/shared/error_messages", resource: resource %>
7
+
8
+ <div class="input-group">
9
+ <%= f.label :name, class:"label" %>
10
+ <%= f.text_field :name, class:"input" %>
11
+ </div>
12
+
13
+ <div class="input-group">
14
+ <%= f.label :email, class:"label" %>
15
+ <%= f.email_field :email, autocomplete: "email", class:"input" %>
16
+ </div>
17
+
18
+ <div class="input-group">
19
+ <div class="flex">
20
+ <%= f.label :password, class: "label" %>
21
+ <% if @minimum_password_length %>
22
+ <span class="pl-1 text-xs text-grey-dark"><em>(<%= @minimum_password_length %> characters minimum)</em></span>
23
+ <% end %>
24
+ </div>
25
+ <%= f.password_field :password, autocomplete: "new-password", class: "input" %>
26
+ </div>
27
+
28
+ <div class="input-group">
29
+ <%= f.label :password_confirmation, class:"label" %>
30
+ <%= f.password_field :password_confirmation, autocomplete: "new-password", class: "input" %>
31
+ </div>
32
+
33
+ <div class="input-group">
34
+ <%= f.submit "Sign up", class: "btn btn-default" %>
35
+ </div>
36
+
37
+ <hr class="mt-6 border" />
38
+
39
+ <% end %>
40
+
41
+ <%= render "devise/shared/links" %>
42
+
43
+ <% end %>
44
+
45
+ <%= render "devise/shared/form_wrap" %>
@@ -0,0 +1,33 @@
1
+ <% content_for :devise_form do %>
2
+ <h2 class="pt-4 mb-8 text-4xl font-bold heading">Log in</h2>
3
+ <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
4
+
5
+ <div class="input-group">
6
+ <%= f.label :email, class:"label" %>
7
+ <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "input" %>
8
+ </div>
9
+
10
+ <div class="input-group">
11
+ <%= f.label :password, class:"label" %>
12
+ <%= f.password_field :password, autocomplete: "current-password", class: "input" %>
13
+ </div>
14
+
15
+ <div class="mb-6 input-checkbox">
16
+ <% if devise_mapping.rememberable? -%>
17
+ <%= f.check_box :remember_me %>
18
+ <%= f.label :remember_me, class:"label" %>
19
+ <% end -%>
20
+ </div>
21
+
22
+ <div class="input-group">
23
+ <%= f.submit "Log in", class: "btn btn-default" %>
24
+ </div>
25
+
26
+ <% end %>
27
+
28
+ <hr class="mt-6 border" />
29
+
30
+ <%= render "devise/shared/links" %>
31
+ <% end %>
32
+
33
+ <%= render "devise/shared/form_wrap" %>
@@ -0,0 +1,15 @@
1
+ <% if resource.errors.any? %>
2
+ <div id="error_explanation" class="text-red-500">
3
+ <h2 class="font-semibold text-lg">
4
+ <%= I18n.t("errors.messages.not_saved",
5
+ count: resource.errors.count,
6
+ resource: resource.class.model_name.human.downcase)
7
+ %>
8
+ </h2>
9
+ <ul class="list-none p-0">
10
+ <% resource.errors.full_messages.each do |message| %>
11
+ <li><%= message %></li>
12
+ <% end %>
13
+ </ul>
14
+ </div>
15
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <div class="w-full max-w-md mx-auto my-8">
2
+ <div class="bg-white border border-gray-300 rounded-lg px-8 pt-6 pb-8">
3
+ <%= yield :devise_form %>
4
+ </div>
5
+ </div>
@@ -0,0 +1,25 @@
1
+ <%- if controller_name != 'sessions' %>
2
+ <div class="flex flex-wrap"><%= link_to "Log in", new_session_path(resource_name), class: "block py-2 text-gray-700 underline hover:no-underline" %></div>
3
+ <% end -%>
4
+
5
+ <%- if devise_mapping.registerable? && controller_name != 'registrations' %>
6
+ <%= link_to "Sign up", new_registration_path(resource_name), class: "block py-2 text-gray-700 underline hover:no-underline" %>
7
+ <% end -%>
8
+
9
+ <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
10
+ <%= link_to "Forgot your password?", new_password_path(resource_name), class: "block py-2 text-gray-700 underline hover:no-underline" %>
11
+ <% end -%>
12
+
13
+ <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
14
+ <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: "block py-2 text-gray-700 underline hover:no-underline"%>
15
+ <% end -%>
16
+
17
+ <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
18
+ <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name), class: "block py-2 text-gray-700 underline hover:no-underline" %>
19
+ <% end -%>
20
+
21
+ <%- if devise_mapping.omniauthable? %>
22
+ <%- resource_class.omniauth_providers.each do |provider| %>
23
+ <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), class: "btn btn-default my-4" %>
24
+ <% end -%>
25
+ <% end -%>
@@ -0,0 +1,22 @@
1
+ <% content_for :devise_form do %>
2
+ <h2 class="pt-4 mb-8 text-4xl font-bold heading">Resend unlock instructions</h2>
3
+
4
+ <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
5
+ <%= render "devise/shared/error_messages", resource: resource %>
6
+
7
+ <div class="input-group">
8
+ <%= f.label :email, class: "label" %>
9
+ <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "input" %>
10
+ </div>
11
+
12
+ <div class="input-group">
13
+ <%= f.submit "Resend unlock instructions", class: "btn btn-default" %>
14
+ </div>
15
+ <% end %>
16
+
17
+ <hr class="mt-6 border"/>
18
+
19
+ <%= render "devise/shared/links" %>
20
+ <% end %>
21
+
22
+ <%= render "devise/shared/form_wrap" %>
@@ -0,0 +1,51 @@
1
+ .git
2
+ .gitignore
3
+ README.md
4
+
5
+ #
6
+ # OS X
7
+ #
8
+ .DS_Store
9
+ .AppleDouble
10
+ .LSOverride
11
+ # Icon must end with two \r
12
+ Icon
13
+ # Thumbnails
14
+ ._*
15
+ # Files that might appear on external disk
16
+ .Spotlight-V100
17
+ .Trashes
18
+ # Directories potentially created on remote AFP share
19
+ .AppleDB
20
+ .AppleDesktop
21
+ Network Trash Folder
22
+ Temporary Items
23
+ .apdisk
24
+
25
+ #
26
+ # Rails
27
+ #
28
+ .env
29
+ .env.sample
30
+ *.rbc
31
+ capybara-*.html
32
+ log
33
+ tmp
34
+ db/*.sqlite3
35
+ db/*.sqlite3-journal
36
+ public/system
37
+ coverage/
38
+ spec/tmp
39
+ **.orig
40
+
41
+ .bundle
42
+
43
+ .ruby-version
44
+ .ruby-gemset
45
+
46
+ .rvmrc
47
+
48
+ # if using bower-rails ignore default bower_components path bower.json files
49
+ vendor/assets/bower_components
50
+ *.bowerrc
51
+ bower.json
@@ -0,0 +1,45 @@
1
+ FROM ruby:3.0-slim as cache
2
+
3
+ RUN apt-get update -qq && apt-get install -y \
4
+ curl \
5
+ build-essential \
6
+ libpq-dev \
7
+ postgresql-client
8
+ RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
9
+
10
+ RUN curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
11
+ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
12
+
13
+ RUN apt-get update -qq && apt-get install -y yarn
14
+
15
+ WORKDIR /bookstore
16
+ COPY Gemfile /<%= app_name %>/Gemfile
17
+ COPY Gemfile.lock /<%= app_name %>/Gemfile.lock
18
+ COPY package.json /<%= app_name %>/package.json
19
+ COPY yarn.lock /<%= app_name %>/yarn.lock
20
+
21
+ RUN bundle install --without development
22
+ RUN yarn install
23
+
24
+ FROM cache
25
+ COPY . /<%= app_name %>
26
+
27
+ ARG DATABASE_HOST=db
28
+ ARG RAILS_ENV=production
29
+
30
+ ENV DATABASE_HOST=$DATABASE_HOST
31
+ ENV RAILS_ENV=$RAILS_ENV
32
+
33
+ ENV RAILS_LOG_TO_STDOUT=true
34
+ ENV RAILS_SERVE_STATIC_FILES=true
35
+
36
+ RUN bundle exec rails assets:precompile
37
+
38
+ COPY entrypoint.sh /usr/bin/
39
+ RUN chmod +x /usr/bin/entrypoint.sh
40
+ ENTRYPOINT ["entrypoint.sh"]
41
+
42
+ EXPOSE 3000
43
+
44
+ # Start the main process.
45
+ CMD ["rails", "server", "-b", "0.0.0.0"]
@@ -0,0 +1,21 @@
1
+ version: "3"
2
+ services:
3
+ <%= app_name %>-db:
4
+ image: postgres
5
+ volumes:
6
+ - <%= app_name %>-data:/var/lib/postgresql/data
7
+ ports:
8
+ - 5432:5432
9
+ environment:
10
+ POSTGRES_PASSWORD: <%= app_name %>
11
+ POSTGRES_USER: <%= app_name %>
12
+
13
+ <%-if uses?(:sidekiq) -%>
14
+ <%= app_name %>-redis:
15
+ image: redis
16
+ ports:
17
+ - 6379:6379
18
+ <%- end -%>
19
+
20
+ volumes:
21
+ <%= app_name %>-data:
@@ -0,0 +1,3 @@
1
+ DATABASE_HOST=localhost
2
+ DATABASE_USERNAME=<%= app_name %>
3
+ DATABASE_PASSWORD=<%= app_name %>
@@ -0,0 +1 @@
1
+ procfile: Procfile.dev
@@ -0,0 +1,7 @@
1
+ <% if uses?(:docker_compose) -%>
2
+ docker: docker-compose up --scale <%= app_name %>=0
3
+ <% end -%>
4
+ <% if uses?(:sidekiq) -%>
5
+ sidekiq: bundle exec sidekiq
6
+ <% end -%>
7
+ web: bundle exec rails server -p 3000
@@ -0,0 +1,4 @@
1
+ web: rails server
2
+ <% if uses?(:sidekiq) -%>
3
+ worker: sidekiq
4
+ <% end -%>
@@ -0,0 +1,6 @@
1
+ Description:
2
+ This adds a link to the specified resource to your home page
3
+
4
+ Example:
5
+ bin/rails generate navigation resource
6
+
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ # Add Navigation bar to Rails application
5
+ class NavigationGenerator < Rails::Generators::NamedBase
6
+ def add_link
7
+ append_to_file 'app/views/shared/_navbar.html.erb',
8
+ after: '<!-- SZ Link Placeholder -->' do
9
+ <<-HTML
10
+
11
+ <%= link_to "#{plural_name.capitalize}", #{plural_name}_path, class: "block md:inline-block p-3 border-b-2 border-gray-100 md:border-none" %>
12
+ HTML
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
5
+
6
+ module Rails
7
+ module Generators
8
+ class ScaffoldControllerGenerator
9
+ hook_for :navigation, type: :boolean, default: true
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ HighVoltage.configure do |config|
4
+ config.route_drawer = HighVoltage::RouteDrawers::Root
5
+ config.home_page = 'home'
6
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'irb/completion'
4
+ require 'irb/ext/save-history'
5
+
6
+ <%# https://docs.ruby-lang.org/en/2.2.0/IRB.html %>
7
+ IRB.conf[:SAVE_HISTORY] = 1000
8
+ IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-history"
9
+ IRB.conf[:PROMPT_MODE] = :SIMPLE
10
+
11
+ <% if uses?(:factory_bot) -%>
12
+ include FactoryBot::Syntax::Methods
13
+ <% end -%>
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails.application.configure do
4
+ config.lograge.enabled = true
5
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AuthorizedController < ApplicationController
4
+ include Pundit
5
+
6
+ before_action :authenticate_user!
7
+
8
+ after_action :verify_authorized, except: :index
9
+ after_action :verify_policy_scoped, only: :index
10
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Pundit ApplicationPolicy
4
+ class ApplicationPolicy
5
+ attr_reader :user, :record
6
+
7
+ def initialize(user, record)
8
+ raise Pundit::NotAuthorizedError, 'must be logged in' unless user
9
+
10
+ @user = user
11
+ @record = record
12
+ end
13
+
14
+ def index?
15
+ false
16
+ end
17
+
18
+ def show?
19
+ false
20
+ end
21
+
22
+ def create?
23
+ false
24
+ end
25
+
26
+ def new?
27
+ false
28
+ end
29
+
30
+ def update?
31
+ false
32
+ end
33
+
34
+ def edit?
35
+ false
36
+ end
37
+
38
+ def destroy?
39
+ false
40
+ end
41
+
42
+ # Pundit ApplicationPolicy - Scope
43
+ class Scope
44
+ attr_reader :user, :scope
45
+
46
+ def initialize(user, scope)
47
+ raise Pundit::NotAuthorizedError, 'must be logged in' unless user
48
+
49
+ @user = user
50
+ @scope = scope
51
+ end
52
+
53
+ def resolve
54
+ scope.all
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ ENV['RAILS_ENV'] ||= 'test'
5
+ require File.expand_path('../config/environment', __dir__)
6
+ # Prevent database truncation if the environment is production
7
+ abort('The Rails environment is running in production mode!') if Rails.env.production?
8
+ require 'rspec/rails'
9
+
10
+ Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
11
+
12
+ # Checks for pending migrations and applies them before tests are run.
13
+ # If you are not using ActiveRecord, you can remove these lines.
14
+ begin
15
+ ActiveRecord::Migration.maintain_test_schema!
16
+ rescue ActiveRecord::PendingMigrationError => e
17
+ puts e.to_s.strip
18
+ exit 1
19
+ end
20
+ RSpec.configure do |config|
21
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
22
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
23
+ config.use_transactional_fixtures = true
24
+ config.infer_spec_type_from_file_location!
25
+ config.filter_rails_from_backtrace!
26
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.configure do |config|
4
+ config.expect_with :rspec do |expectations|
5
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
6
+ end
7
+
8
+ config.mock_with :rspec do |mocks|
9
+ mocks.verify_partial_doubles = true
10
+ end
11
+
12
+ config.shared_context_metadata_behavior = :apply_to_host_groups
13
+
14
+ # The settings below are suggested to provide a good initial experience
15
+ # with RSpec, but feel free to customize to your heart's content.
16
+ # This allows you to limit a spec run to individual examples or groups
17
+ # you care about by tagging them with `:focus` metadata. When nothing
18
+ # is tagged with `:focus`, all examples get run. RSpec also provides
19
+ # aliases for `it`, `describe`, and `context` that include `:focus`
20
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
21
+ config.filter_run_when_matching :focus
22
+
23
+ # Allows RSpec to persist some state between runs in order to support
24
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
25
+ # you configure your source control system to ignore this file.
26
+ config.example_status_persistence_file_path = 'spec/examples.txt'
27
+
28
+ # Limits the available syntax to the non-monkey patched syntax that is
29
+ # recommended. For more details, see:
30
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
31
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
32
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
33
+ config.disable_monkey_patching!
34
+
35
+ # Many RSpec users commonly either run the entire suite or an individual
36
+ # file, and it's useful to allow more verbose output when running an
37
+ # individual spec file.
38
+ if config.files_to_run.one?
39
+ # Use the documentation formatter for detailed output,
40
+ # unless a formatter has already been configured
41
+ # (e.g. via a command-line flag).
42
+ config.default_formatter = 'doc'
43
+ end
44
+
45
+ # Print the 10 slowest examples and example groups at the
46
+ # end of the spec run, to help surface which specs are running
47
+ # particularly slow.
48
+ config.profile_examples = 10
49
+
50
+ # Run specs in random order to surface order dependencies. If you find an
51
+ # order dependency and want to debug it, you can fix the order by providing
52
+ # the seed, which is printed after each run.
53
+ # --seed 1234
54
+ config.order = :random
55
+
56
+ # Seed global randomization in this process using the `--seed` CLI option.
57
+ # Setting this allows you to use `--seed` to deterministically reproduce
58
+ # test failures related to randomization by passing the same `--seed` value
59
+ # as the one that triggered the failure.
60
+ Kernel.srand config.seed
61
+ end
@@ -0,0 +1,37 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ Exclude:
4
+ - bin/*
5
+ - db/schema.rb
6
+ - db/migrate/*
7
+ - node_modules/**/*
8
+
9
+ Naming/AccessorMethodName:
10
+ Enabled: false
11
+
12
+ Metrics/MethodLength:
13
+ CountAsOne: ['array', 'heredoc']
14
+ IgnoredMethods: ['describe', 'context']
15
+
16
+ Metrics/BlockLength:
17
+ IgnoredMethods: ['describe', 'context']
18
+ Exclude:
19
+ - config/environments/*.rb
20
+ - '**/*.rake'
21
+
22
+ Layout/LineLength:
23
+ Max: 120
24
+
25
+ Layout/MultilineMethodCallIndentation:
26
+ EnforcedStyle: indented
27
+
28
+ Lint/EmptyBlock:
29
+ Exclude:
30
+ - spec/factories/*
31
+
32
+ Style/BlockDelimiters:
33
+ Exclude:
34
+ - spec/**/*
35
+
36
+ Style/Documentation:
37
+ Enabled: false
@@ -0,0 +1,39 @@
1
+ <%%= form_with(model: <%= model_resource_name %>) do |form| %>
2
+ <%% if <%= singular_table_name %>.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
5
+
6
+ <ul>
7
+ <%% <%= singular_table_name %>.errors.each do |error| %>
8
+ <li><%%= error.full_message %></li>
9
+ <%% end %>
10
+ </ul>
11
+ </div>
12
+ <%% end %>
13
+
14
+ <% attributes.each do |attribute| -%>
15
+ <div class="mb-6">
16
+ <% if attribute.password_digest? -%>
17
+ <%%= form.label :password, class: "label" %>
18
+ <%%= form.password_field :password, class: "input" %>
19
+ </div>
20
+ <div class="mb-6">
21
+ <%%= form.label :password_confirmation, class: "label" %>
22
+ <%%= form.password_field :password_confirmation, class: "input" %>
23
+ <% else %>
24
+ <%%= form.label :<%= attribute.column_name %>, class: "label" %>
25
+ <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, class: "input" %>
26
+ <% end %>
27
+ </div>
28
+
29
+ <% end -%>
30
+ <div class="mt-2 flex justify-between items-center">
31
+ <%%= link_to 'Back', <%= index_helper %>_path, class: "btn btn-default" %>
32
+ <div class="flex">
33
+ <%%= form.button class: "btn btn-default" %>
34
+ <%% if form.object.persisted? %>
35
+ <%%= link_to 'Delete', form.object, class: "btn btn-default", method: :delete, data: { remote: true, confirm: "Are you sure?" }, class: "btn btn-warn" %>
36
+ <%% end %>
37
+ </div>
38
+ </div>
39
+ <%% end %>
@@ -0,0 +1,7 @@
1
+ <div class="container mx-auto my-8 px-4">
2
+ <h1 class="text-4xl">Editing <%= plural_table_name.titleize %></h1>
3
+
4
+ <div class="bg-white rounded shadow p-4">
5
+ <%%= render 'form', <%= singular_table_name %>: @<%= singular_table_name %> %>
6
+ </div>
7
+ </div>