rails_app_generator 0.2.21 → 0.2.24
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.
- checksums.yaml +4 -4
- data/.builders/generators/project-plan.rb +16 -2
- data/CHANGELOG.md +24 -0
- data/after_templates/addons/avo/_.rb +54 -0
- data/after_templates/addons/avo/app/controllers/home_controller.rb +4 -0
- data/after_templates/addons/avo/app/views/home/index.html.erb +3 -0
- data/after_templates/addons/avo/app/views/layouts/_footer.html.erb +3 -0
- data/after_templates/addons/avo/app/views/layouts/_navbar.html.erb +8 -0
- data/after_templates/addons/avo/app/views/layouts/application.html.erb +23 -0
- data/after_templates/addons/avo/db/seeds.rb +132 -0
- data/after_templates/addons/devise/_.rb +70 -0
- data/after_templates/addons/devise/app/controllers/home_controller.rb +4 -0
- data/after_templates/addons/devise/app/controllers/posts_controller.rb +81 -0
- data/after_templates/addons/devise/app/models/post.rb +11 -0
- data/after_templates/addons/devise/app/models/user.rb +17 -0
- data/after_templates/addons/devise/app/views/home/index.html.erb +40 -0
- data/after_templates/addons/devise/app/views/layouts/_footer.html.erb +1 -0
- data/after_templates/addons/devise/app/views/layouts/_navbar.html.erb +10 -0
- data/after_templates/addons/devise/app/views/layouts/application.html.erb +38 -0
- data/after_templates/addons/devise/app/views/posts/_form.html.erb +27 -0
- data/after_templates/addons/devise/app/views/posts/_post.html.erb +14 -0
- data/after_templates/addons/devise/app/views/posts/index.html.erb +12 -0
- data/after_templates/addons/devise/app/views/posts/show.html.erb +8 -0
- data/after_templates/addons/devise/db/seeds.rb +11 -0
- data/after_templates/addons/minimal_css/_.rb +62 -0
- data/after_templates/addons/minimal_css/app/controllers/home_controller.rb +4 -0
- data/after_templates/addons/minimal_css/app/views/home/index.html.erb +140 -0
- data/after_templates/addons/minimal_css/app/views/layouts/_footer.html.erb +1 -0
- data/after_templates/addons/minimal_css/app/views/layouts/_navbar.html.erb +3 -0
- data/after_templates/addons/minimal_css/app/views/layouts/application.html.erb +29 -0
- data/after_templates/addons/minimal_css/db/seeds.rb +5 -0
- data/after_templates/rag/devise/_.rb +14 -17
- data/after_templates/rag/devise/app/controllers/home_controller.rb +4 -0
- data/after_templates/rag/devise/{post → app/controllers}/posts_controller.rb +0 -0
- data/after_templates/rag/devise/{post → app/models}/post.rb +0 -0
- data/after_templates/rag/devise/app/views/home/index.html.erb +3 -0
- data/after_templates/rag/devise/app/views/layouts/_footer.html.erb +3 -0
- data/after_templates/rag/devise/app/views/layouts/_navbar.html.erb +8 -0
- data/after_templates/rag/devise/app/views/layouts/application.html.erb +24 -0
- data/after_templates/rag/devise/{post → app/views/post}/_post.html.erb +0 -0
- data/after_templates/rag/test/_.rb +64 -0
- data/after_templates/rag/test/app/controllers/home_controller.rb +4 -0
- data/after_templates/rag/test/app/views/home/index.html.erb +3 -0
- data/after_templates/rag/test/app/views/layouts/_footer.html.erb +1 -0
- data/after_templates/rag/test/app/views/layouts/_navbar.html.erb +5 -0
- data/after_templates/rag/test/app/views/layouts/application.html.erb +29 -0
- data/after_templates/rag/test/db/seeds.rb +7 -0
- data/after_templates/rag/testy/_.rb +64 -0
- data/after_templates/rag/testy/app/controllers/home_controller.rb +4 -0
- data/after_templates/rag/testy/app/views/home/index.html.erb +3 -0
- data/after_templates/rag/testy/app/views/layouts/_footer.html.erb +1 -0
- data/after_templates/rag/testy/app/views/layouts/_navbar.html.erb +5 -0
- data/after_templates/rag/testy/app/views/layouts/application.html.erb +29 -0
- data/after_templates/rag/testy/db/seeds.rb +7 -0
- data/docs/last_run/app_generator_class.json +58 -34
- data/docs/last_run/app_generator_data.json +13 -10
- data/docs/last_run/rails_options_class.json +48 -24
- data/docs/last_run/rails_options_data.json +13 -10
- data/docs/project-plan/project.drawio +65 -59
- data/docs/project-plan/project_done.svg +1 -1
- data/lib/rails_app_generator/addon.rb +20 -2
- data/lib/rails_app_generator/addons/avo.rb +27 -0
- data/lib/rails_app_generator/addons/devise.rb +78 -28
- data/lib/rails_app_generator/addons/devise_old.rb +22 -0
- data/lib/rails_app_generator/addons/minimal_css.rb +70 -0
- data/lib/rails_app_generator/app_generator.rb +39 -20
- data/lib/rails_app_generator/gem_query.rb +34 -0
- data/lib/rails_app_generator/rag_initializer.rb +24 -8
- data/lib/rails_app_generator/version.rb +1 -1
- data/lib/rails_app_generator.rb +1 -0
- data/package-lock.json +2 -2
- data/package.json +1 -1
- data/profiles/addons/avo.json +16 -0
- data/profiles/addons/devise.json +16 -0
- data/profiles/addons/minimal_css.json +15 -0
- data/profiles/rag/testy.json +12 -0
- data/tasks/addon.thor +7 -3
- data/tasks/profile.thor +3 -3
- data/templates/Gemfile.erb +1 -0
- data/{after_templates/rag/devise/turbo_controller.rb → templates/addons/devise/app/controllers/turbo_devise_controller.rb} +4 -10
- data/templates/addons/devise/app/controllers/users/registrations_controller.rb +62 -0
- data/templates/addons/devise/app/views/devise/registrations/edit.html.erb +40 -54
- data/templates/addons/devise/app/views/devise/registrations/new.html.erb +32 -43
- data/templates/addons/devise/app/views/layouts/_alerts.html.erb +2 -0
- data/{after_templates/rag → templates/addons}/devise/config/initializers/devise_turbo.rb +1 -1
- data/templates/thor_task/profile/after_template.rb +1 -1
- data/templates/thor_task/profile/app/views/layouts/_footer.html.erb.tt +1 -3
- data/templates/thor_task/profile/app/views/layouts/_navbar.html.erb +5 -8
- data/templates/thor_task/profile/app/views/layouts/application.html.erb.tt +8 -2
- data/templates/thor_task/profile/db/seeds.rb +2 -11
- metadata +64 -17
- data/after_templates/rag/devise/application.html.erb +0 -20
- data/tasks/gem_info.rb +0 -47
- data/templates/addons/devise/app/views/devise/confirmations/new.html.erb +0 -24
- data/templates/addons/devise/app/views/devise/passwords/edit.html.erb +0 -34
- data/templates/addons/devise/app/views/devise/passwords/new.html.erb +0 -23
- data/templates/addons/devise/app/views/devise/sessions/new.html.erb +0 -33
- data/templates/addons/devise/app/views/devise/shared/_error_messages.html.erb +0 -15
- data/templates/addons/devise/app/views/devise/shared/_form_wrap.html.erb +0 -5
- data/templates/addons/devise/app/views/devise/shared/_links.html.erb +0 -25
- data/templates/addons/devise/app/views/devise/unlocks/new.html.erb +0 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f3b2288ae71fcb62d6d27a0c112af620c7ccebf29dad7f7a3ccf0b6b763960bd
|
|
4
|
+
data.tar.gz: 66acd6ef9f7663d0f71605564fa793e88e2f7c4c10427da39b21259cf9cb8ee4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f58098fef783d509ff3005a5687c5d576c02b827ecb252b90e15f0150a73301d268dc4bd37412618b53bf4d82f21e60b02b9c46ae84ee0351ae9ddc85cc335bc
|
|
7
|
+
data.tar.gz: 02e741081aeec1eca92b1ae4260831cd0b556a243c98b3147c76b446b793d9fa1bee52949819bf02255dc00c0d9257192224fe8516834354f9d02fdf71a1017b
|
|
@@ -41,20 +41,34 @@ KManager.action :project_plan do
|
|
|
41
41
|
|
|
42
42
|
todo(title: 'add addon - acts_as_list')
|
|
43
43
|
todo(title: 'add addon - administrate')
|
|
44
|
+
todo(title: 'add addon - annotate')
|
|
44
45
|
todo(title: 'add addon - bcrypt')
|
|
45
46
|
todo(title: 'add addon - browser')
|
|
46
47
|
todo(title: 'add addon - chartkick')
|
|
48
|
+
# continuous_integration
|
|
49
|
+
# devise
|
|
50
|
+
# docker_compose
|
|
51
|
+
# docker
|
|
47
52
|
todo(title: 'add addon - dotenv')
|
|
53
|
+
# factory_bot
|
|
48
54
|
todo(title: 'add addon - faker')
|
|
55
|
+
# generators
|
|
56
|
+
todo(title: 'add addon - groupdate')
|
|
49
57
|
todo(title: 'add addon - hexapdf')
|
|
50
|
-
todo(title: 'add addon - honeybadger')
|
|
51
58
|
todo(title: 'add addon - httparty')
|
|
59
|
+
# high_voltage
|
|
60
|
+
todo(title: 'add addon - honeybadger')
|
|
52
61
|
todo(title: 'add addon - lograge')
|
|
53
62
|
todo(title: 'add addon - mini_magick')
|
|
54
63
|
todo(title: 'add addon - motor_magick')
|
|
55
|
-
todo(title: 'add addon - phony_rails')
|
|
56
64
|
todo(title: 'add addon - public_suffix')
|
|
65
|
+
todo(title: 'add addon - phony_rails')
|
|
66
|
+
# pundit
|
|
57
67
|
todo(title: 'add addon - rails_html_sanitizer')
|
|
68
|
+
# rails_app_generator
|
|
69
|
+
# services
|
|
70
|
+
# shoulda
|
|
71
|
+
# sidekiq
|
|
58
72
|
todo(title: 'add addon - redcarpet')
|
|
59
73
|
todo(title: 'add addon - groupdate')
|
|
60
74
|
todo(title: 'add addon - rubocop')
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
## [0.2.23](https://github.com/klueless-io/rails_app_generator/compare/v0.2.22...v0.2.23) (2022-08-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* add devise profile ([a665767](https://github.com/klueless-io/rails_app_generator/commit/a6657670b1fce4eb802a56ace36368505ede3c2e))
|
|
7
|
+
* fix invalid gem ([377e547](https://github.com/klueless-io/rails_app_generator/commit/377e5479c4debbd0df9e1362694d1847cf7d58e0))
|
|
8
|
+
* update addon to work with non gems ([f9b0b14](https://github.com/klueless-io/rails_app_generator/commit/f9b0b147859760abbb921a236cd1e7f6a97eb3f0))
|
|
9
|
+
|
|
10
|
+
## [0.2.22](https://github.com/klueless-io/rails_app_generator/compare/v0.2.21...v0.2.22) (2022-08-14)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* update avo profile ([79a3f36](https://github.com/klueless-io/rails_app_generator/commit/79a3f366f9f95e29a5f003a815c1fc963d796179))
|
|
16
|
+
* update avo profile ([2830ddf](https://github.com/klueless-io/rails_app_generator/commit/2830ddff3fd327d2c162ef1e0128dc525b3a493c))
|
|
17
|
+
|
|
18
|
+
## [0.2.21](https://github.com/klueless-io/rails_app_generator/compare/v0.2.20...v0.2.21) (2022-08-12)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* add annotate profile ([1794612](https://github.com/klueless-io/rails_app_generator/commit/17946124c5600881a4d015c3283fc9e2e3278634))
|
|
24
|
+
|
|
1
25
|
## [0.2.20](https://github.com/klueless-io/rails_app_generator/compare/v0.2.19...v0.2.20) (2022-08-12)
|
|
2
26
|
|
|
3
27
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Avo abstracts away the common parts of building apps, letting your engineers work on your app's essential components. The result is a full-featured admin panel that works out of the box, ready to give to your end-users.
|
|
4
|
+
#
|
|
5
|
+
# exe/rag addons/avo
|
|
6
|
+
#
|
|
7
|
+
# based on: https://www.youtube.com/watch?v=WgNK-oINFww
|
|
8
|
+
|
|
9
|
+
self.local_template_path = File.dirname(__FILE__)
|
|
10
|
+
|
|
11
|
+
gac 'base rails 7 image created'
|
|
12
|
+
|
|
13
|
+
prepare_environment
|
|
14
|
+
|
|
15
|
+
add_controller('home', 'index')
|
|
16
|
+
|
|
17
|
+
route("root 'home#index'")
|
|
18
|
+
|
|
19
|
+
force_copy
|
|
20
|
+
|
|
21
|
+
directory "app/controllers"
|
|
22
|
+
directory "app/views/home"
|
|
23
|
+
directory "app/views/layouts"
|
|
24
|
+
template 'app/views/layouts/application.html.erb' , 'app/views/layouts/application.html.erb'
|
|
25
|
+
|
|
26
|
+
template 'db/seeds.rb' , 'db/seeds.rb'
|
|
27
|
+
|
|
28
|
+
after_bundle do
|
|
29
|
+
setup_db
|
|
30
|
+
setup_avo
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def setup_db
|
|
34
|
+
add_scaffold('author', 'name:string', 'email:string', 'bio:text')
|
|
35
|
+
add_scaffold('category', 'title:string', 'description:text')
|
|
36
|
+
add_scaffold('post', 'title:string content:text', 'published:boolean', 'author:references', 'category:references')
|
|
37
|
+
add_scaffold('product', 'name', 'quantity:integer', 'price:decimal', 'author:references')
|
|
38
|
+
|
|
39
|
+
db_migrate
|
|
40
|
+
db_seed
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def setup_avo
|
|
44
|
+
generate('avo:install')
|
|
45
|
+
generate('avo:resource Product')
|
|
46
|
+
generate('avo:resource Post')
|
|
47
|
+
generate('avo:resource Author')
|
|
48
|
+
generate('avo:resource Category')
|
|
49
|
+
generate('avo:resource User')
|
|
50
|
+
generate('avo:dashboard Dashboard')
|
|
51
|
+
|
|
52
|
+
# add devise support
|
|
53
|
+
gsub_file 'config/initializers/avo.rb', %(# config.current_user_method = {}), 'config.current_user_method = :current_user'
|
|
54
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title><%= camelized %></title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<%%= csrf_meta_tags %>
|
|
7
|
+
<%%= csp_meta_tag %>
|
|
8
|
+
|
|
9
|
+
<%- if options[:skip_hotwire] || options[:skip_javascript] -%>
|
|
10
|
+
<%%= stylesheet_link_tag "application" %>
|
|
11
|
+
<%- else -%>
|
|
12
|
+
<%%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
|
13
|
+
<%- end -%>
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
<%%= render 'layouts/navbar' %>
|
|
18
|
+
<main>
|
|
19
|
+
<%%= yield %>
|
|
20
|
+
</main>
|
|
21
|
+
<%%= render 'layouts/footer' %>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
def fake_category
|
|
2
|
+
[
|
|
3
|
+
'Action',
|
|
4
|
+
'Adventure',
|
|
5
|
+
'Biography',
|
|
6
|
+
'Comedy',
|
|
7
|
+
'Crime',
|
|
8
|
+
'Drama',
|
|
9
|
+
'Fantasy',
|
|
10
|
+
]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def fake_title
|
|
14
|
+
[
|
|
15
|
+
'Fundamentals of Wavelets',
|
|
16
|
+
'Data Smart',
|
|
17
|
+
'God Created the Integers',
|
|
18
|
+
'Superfreakonomics',
|
|
19
|
+
'Orientalism',
|
|
20
|
+
'Nature of Statistical Learning Theory',
|
|
21
|
+
'Integration of the Indian States',
|
|
22
|
+
'Image Processing & Mathematical Morphology',
|
|
23
|
+
'How to Think Like Sherlock Holmes',
|
|
24
|
+
'Data Scientists at Work',
|
|
25
|
+
'Slaughterhouse Five',
|
|
26
|
+
'Birth of a Theorem',
|
|
27
|
+
'Structure & Interpretation of Computer Programs',
|
|
28
|
+
'Age of Wrath',
|
|
29
|
+
'Trial',
|
|
30
|
+
'Data Mining Handbook',
|
|
31
|
+
'New Machiavelli',
|
|
32
|
+
'Physics & Philosophy',
|
|
33
|
+
'Making Software',
|
|
34
|
+
'Analysis',
|
|
35
|
+
'Machine Learning for Hackers',
|
|
36
|
+
'Signal and the Noise',
|
|
37
|
+
'Python for Data Analysis',
|
|
38
|
+
'Introduction to Algorithms',
|
|
39
|
+
'Beautiful and the Damned',
|
|
40
|
+
'Outsider',
|
|
41
|
+
'Complete Sherlock Holmes',
|
|
42
|
+
'Complete Sherlock Holmes',
|
|
43
|
+
'Wealth of Nations',
|
|
44
|
+
'Pillars of the Earth',
|
|
45
|
+
'Mein Kampf',
|
|
46
|
+
'Tao of Physics',
|
|
47
|
+
'Farewell to Arms',
|
|
48
|
+
'Veteran',
|
|
49
|
+
'False Impressions',
|
|
50
|
+
'Last Lecture',
|
|
51
|
+
'Return of the Primitive',
|
|
52
|
+
'Jurassic Park',
|
|
53
|
+
'Russian Journal',
|
|
54
|
+
'Tales of Mystery and Imagination',
|
|
55
|
+
'Freakonomics',
|
|
56
|
+
'Hidden Connections',
|
|
57
|
+
'Story of Philosophy',
|
|
58
|
+
'Asami Asami',
|
|
59
|
+
'Journal of a Novel',
|
|
60
|
+
'Once There Was a War',
|
|
61
|
+
'Moon is Down',
|
|
62
|
+
'Brethren',
|
|
63
|
+
'In a Free State',
|
|
64
|
+
'Catch 22',
|
|
65
|
+
'Complete Mastermind',
|
|
66
|
+
'Dylan on Dylan',
|
|
67
|
+
'Soft Computing & Intelligent Systems',
|
|
68
|
+
'Textbook of Economic Theory',
|
|
69
|
+
'Econometric Analysis',
|
|
70
|
+
'Learning OpenCV',
|
|
71
|
+
'Data Structures Using C & C++',
|
|
72
|
+
'Computer Vision',
|
|
73
|
+
'Principles of Communication Systems',
|
|
74
|
+
'Let Us C',
|
|
75
|
+
'Amulet of Samarkand',
|
|
76
|
+
'Crime and Punishment',
|
|
77
|
+
'Angels & Demons',
|
|
78
|
+
'Argumentative Indian',
|
|
79
|
+
'Sea of Poppies',
|
|
80
|
+
'Idea of Justice',
|
|
81
|
+
'Raisin in the Sun',
|
|
82
|
+
'Prisoner of Birth',
|
|
83
|
+
'Scoop!',
|
|
84
|
+
'Ahe Manohar Tari',
|
|
85
|
+
'Last Mughal',
|
|
86
|
+
'Social Choice & Welfare',
|
|
87
|
+
'Radiowaril Bhashane & Shrutika',
|
|
88
|
+
'Gun Gayin Awadi',
|
|
89
|
+
'Aghal Paghal',
|
|
90
|
+
'Beyond Degrees',
|
|
91
|
+
'Manasa',
|
|
92
|
+
'India from Midnight to Milennium',
|
|
93
|
+
'Great Indian Novel',
|
|
94
|
+
'O Jerusalem!',
|
|
95
|
+
'City of Joy',
|
|
96
|
+
'Freedom at Midnight',
|
|
97
|
+
'Winter of Our Discontent',
|
|
98
|
+
'On Education',
|
|
99
|
+
'Free Will',
|
|
100
|
+
'Bookless in Baghdad',
|
|
101
|
+
'Case of the Lame Canary',
|
|
102
|
+
'Theory of Everything',
|
|
103
|
+
'New Markets & Other Essays',
|
|
104
|
+
'Electric Universe',
|
|
105
|
+
'Hunchback of Notre Dame',
|
|
106
|
+
'Burning Bright',
|
|
107
|
+
'Age of Discontuinity'
|
|
108
|
+
].sample
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
60.times do
|
|
112
|
+
Author.create!(name: Faker::Name.name, bio: Faker::Lorem.words(number: 5).join(' '), email: Faker::Internet.email)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
fake_category.each do |category|
|
|
116
|
+
Category.create!(title: category, description: Faker::Lorem.sentence)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
100.times do |i|
|
|
120
|
+
Post.create!(title: fake_title,
|
|
121
|
+
content: "This is the body of post #{i}",
|
|
122
|
+
published: Faker::Boolean.boolean(true_ratio: 0.6),
|
|
123
|
+
author: Author.all.sample)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
200.times do
|
|
127
|
+
Product.create!(
|
|
128
|
+
name: Faker::Name.name,
|
|
129
|
+
quantity: Faker::Number.number(digits: 2),
|
|
130
|
+
price: Faker::Number.decimal(l_digits: 4)
|
|
131
|
+
)
|
|
132
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Based on guidance from:
|
|
4
|
+
# Rails 7 - Intro to Devise
|
|
5
|
+
# https://www.youtube.com/watch?v=m3uhldUGVes
|
|
6
|
+
#
|
|
7
|
+
# exe/rag addons/devise
|
|
8
|
+
|
|
9
|
+
self.local_template_path = File.dirname(__FILE__)
|
|
10
|
+
|
|
11
|
+
gac 'base rails 7 image created'
|
|
12
|
+
|
|
13
|
+
prepare_environment
|
|
14
|
+
|
|
15
|
+
after_bundle do
|
|
16
|
+
scaffolds
|
|
17
|
+
setup_customizations
|
|
18
|
+
setup_db
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def scaffolds
|
|
22
|
+
add_scaffold('post', 'title', 'body:text', 'views:integer', 'user:references')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def setup_db
|
|
26
|
+
template 'db/seeds.rb' , 'db/seeds.rb'
|
|
27
|
+
|
|
28
|
+
db_migrate
|
|
29
|
+
db_seed
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def setup_customizations
|
|
33
|
+
route("root 'home#index'")
|
|
34
|
+
|
|
35
|
+
force_copy
|
|
36
|
+
|
|
37
|
+
add_controller('home', 'index')
|
|
38
|
+
|
|
39
|
+
directory "app/controllers"
|
|
40
|
+
directory "app/models"
|
|
41
|
+
directory "app/views"
|
|
42
|
+
template 'app/views/layouts/application.html.erb' , 'app/views/layouts/application.html.erb'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Other template command examples
|
|
46
|
+
# prepare_environment
|
|
47
|
+
# bundle_install
|
|
48
|
+
# css_install('tailwind')
|
|
49
|
+
# rails_command('db:migrate')
|
|
50
|
+
# rails_command('db:migrate')
|
|
51
|
+
# bundle_add('hotwire-rails')
|
|
52
|
+
# rails_command('hotwire:install')
|
|
53
|
+
# run('bin/importmap pin sortablejs')
|
|
54
|
+
# run('npm install daisyui')
|
|
55
|
+
# rubocop
|
|
56
|
+
#
|
|
57
|
+
# directory 'app/assets/images'
|
|
58
|
+
# create_file 'app/assets/stylesheets/custom-bootstrap-import.scss' , read_template('custom-bootstrap-import.scss')
|
|
59
|
+
# append_to_file 'app/assets/config/manifest.js' , read_template('manifest.js')
|
|
60
|
+
# insert_into_file 'app/views/layouts/application.html.erb', read_template('application.html.erb'),
|
|
61
|
+
# before: %( <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>)
|
|
62
|
+
# gsub_file 'app/views/layouts/application.html.erb', %(container mx-auto mt-28 px-5 flex), 'container mx-auto px-5'
|
|
63
|
+
# template 'home.css', 'app/assets/stylesheets/home.css'
|
|
64
|
+
#
|
|
65
|
+
# add_controller('page', 'benefits', 'faq', 'terms', 'privacy', '--skip-routes')
|
|
66
|
+
# route(<<-'RUBY')
|
|
67
|
+
# PageController.action_methods.each do |action|
|
|
68
|
+
# get "/#{action}", to: "page##{action}", as: "page_#{action}"
|
|
69
|
+
# end
|
|
70
|
+
# RUBY
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
class PostsController < ApplicationController
|
|
2
|
+
before_action :authenticate_user!, except: %i[show index]
|
|
3
|
+
before_action :set_post, only: %i[show edit update destroy]
|
|
4
|
+
before_action :require_permission, only: %i[edit destroy]
|
|
5
|
+
|
|
6
|
+
def index
|
|
7
|
+
@posts = Post.all.order(updated_at: :desc)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def show
|
|
11
|
+
@post.update(views: @post.views + 1)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def new
|
|
15
|
+
@post = Post.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def edit
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create
|
|
22
|
+
@post = Post.new(post_params)
|
|
23
|
+
@post.user = current_user
|
|
24
|
+
|
|
25
|
+
respond_to do |format|
|
|
26
|
+
if @post.save
|
|
27
|
+
format.html { redirect_to post_url(@post), notice: "Post was successfully created." }
|
|
28
|
+
format.json { render :show, status: :created, location: @post }
|
|
29
|
+
else
|
|
30
|
+
format.html { render :new, status: :unprocessable_entity }
|
|
31
|
+
format.json { render json: @post.errors, status: :unprocessable_entity }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def update
|
|
37
|
+
respond_to do |format|
|
|
38
|
+
if @post.update(post_params)
|
|
39
|
+
format.html { redirect_to post_url(@post), notice: "Post was successfully updated." }
|
|
40
|
+
format.json { render :show, status: :ok, location: @post }
|
|
41
|
+
else
|
|
42
|
+
format.html { render :edit, status: :unprocessable_entity }
|
|
43
|
+
format.json { render json: @post.errors, status: :unprocessable_entity }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def destroy
|
|
49
|
+
@post.destroy
|
|
50
|
+
|
|
51
|
+
respond_to do |format|
|
|
52
|
+
format.html { redirect_to posts_url, notice: "Post was successfully destroyed." }
|
|
53
|
+
format.json { head :no_content }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
def set_post
|
|
59
|
+
@post = Post.find(params[:id])
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def post_params
|
|
63
|
+
params.require(:post).permit(:title, :body, :views, :user_id)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def require_permission
|
|
67
|
+
current_user_name = current_user.name.capitalize
|
|
68
|
+
post_user_name = @post.user.name.capitalize
|
|
69
|
+
post_user_name_plural = "#{post_user_name}#{post_user_name.ends_with?('s') ? "'" : "s"}"
|
|
70
|
+
|
|
71
|
+
flash.notice = "#{current_user_name} is trying to #{action_name} #{post_user_name_plural} post."
|
|
72
|
+
|
|
73
|
+
return if current_user.admin? # Administrators can do anything
|
|
74
|
+
return if current_user.moderator? && action_name == "edit" # Moderators can edit any post (but not delete)
|
|
75
|
+
return if current_user.user? && @post.user == current_user # Users can edit or delete their own posts
|
|
76
|
+
|
|
77
|
+
flash.alert = "You do not have permission to #{action_name} #{post_user_name_plural} post."
|
|
78
|
+
|
|
79
|
+
redirect_back(fallback_location: root_path)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class User < ApplicationRecord
|
|
2
|
+
after_initialize :set_default_role, if: :new_record?
|
|
3
|
+
|
|
4
|
+
# Include default devise modules. Others available are:
|
|
5
|
+
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
|
6
|
+
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable
|
|
7
|
+
|
|
8
|
+
has_many :posts
|
|
9
|
+
|
|
10
|
+
enum role: { user: 0, moderator: 1, admin: 9 }
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def set_default_role
|
|
15
|
+
self.role ||= :user
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<h1>Devise</h1>
|
|
2
|
+
|
|
3
|
+
<h4>Using a simple Enum based Role for permissions</h4>
|
|
4
|
+
|
|
5
|
+
<ul>
|
|
6
|
+
<li>Anyone can view posts</li>
|
|
7
|
+
<li>Only signed in users can create, update or delete a post</li>
|
|
8
|
+
<li>If role <b>user</b>, you can update and delete your own posts only</li>
|
|
9
|
+
<li>If role <b>moderator</b>, you can update any post, but only delete your own posts</li>
|
|
10
|
+
<li>If role <b>admin</b>, you can update or delete any post</li>
|
|
11
|
+
</ul>
|
|
12
|
+
|
|
13
|
+
<h3>Sample users and passwords</h3>
|
|
14
|
+
|
|
15
|
+
<style>
|
|
16
|
+
table {
|
|
17
|
+
border-collapse: collapse;
|
|
18
|
+
}
|
|
19
|
+
th, td {
|
|
20
|
+
border: 1px solid #ccc;
|
|
21
|
+
padding: 5px;
|
|
22
|
+
}
|
|
23
|
+
</style>
|
|
24
|
+
|
|
25
|
+
<table style='width: 600px;'>
|
|
26
|
+
<tr>
|
|
27
|
+
<th>Name</th>
|
|
28
|
+
<th>Email</th>
|
|
29
|
+
<th>Role</th>
|
|
30
|
+
<th>Password</th>
|
|
31
|
+
</tr>
|
|
32
|
+
<% User.all.each do |user| %>
|
|
33
|
+
<tr>
|
|
34
|
+
<td><%= user.name %></td>
|
|
35
|
+
<td><%= user.email %></td>
|
|
36
|
+
<td><%= user.role %></td>
|
|
37
|
+
<td>password</td>
|
|
38
|
+
</tr>
|
|
39
|
+
<% end %>
|
|
40
|
+
</table>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<hr />
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<%= link_to 'Home', root_path %>
|
|
2
|
+
| <%= link_to 'Posts', posts_path %>
|
|
3
|
+
<% if current_user %>
|
|
4
|
+
<%= current_user.name || current_user.email %>
|
|
5
|
+
| <%= link_to 'Edit', edit_user_registration_path %>
|
|
6
|
+
| <%= link_to 'Sign Out', destroy_user_session_path, data: { turbo_method: :delete } %>
|
|
7
|
+
<% else %>
|
|
8
|
+
| <%= link_to 'Sign Up', new_user_registration_path %>
|
|
9
|
+
| <%= link_to 'Sign In', new_user_session_path %>
|
|
10
|
+
<% end%>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title><%= camelized %></title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<%%= csrf_meta_tags %>
|
|
7
|
+
<%%= csp_meta_tag %>
|
|
8
|
+
|
|
9
|
+
<%- if options[:skip_hotwire] || options[:skip_javascript] -%>
|
|
10
|
+
<%%= stylesheet_link_tag "application" %>
|
|
11
|
+
<%- else -%>
|
|
12
|
+
<%%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
|
13
|
+
<%- end -%>
|
|
14
|
+
<%%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
|
|
15
|
+
<style>
|
|
16
|
+
.notice {
|
|
17
|
+
color: green;
|
|
18
|
+
}
|
|
19
|
+
.alert {
|
|
20
|
+
color: red;
|
|
21
|
+
}
|
|
22
|
+
</style>
|
|
23
|
+
</head>
|
|
24
|
+
|
|
25
|
+
<body>
|
|
26
|
+
<header>
|
|
27
|
+
<%%= render 'layouts/navbar' %>
|
|
28
|
+
<hr />
|
|
29
|
+
<%%= render 'layouts/alerts' %>
|
|
30
|
+
</header>
|
|
31
|
+
<main>
|
|
32
|
+
<%%= yield %>
|
|
33
|
+
</main>
|
|
34
|
+
<footer>
|
|
35
|
+
<%%= render 'layouts/footer' %>
|
|
36
|
+
</footer>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<%= form_with(model: post) do |form| %>
|
|
2
|
+
<% if post.errors.any? %>
|
|
3
|
+
<div style="color: red">
|
|
4
|
+
<h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>
|
|
5
|
+
|
|
6
|
+
<ul>
|
|
7
|
+
<% post.errors.each do |error| %>
|
|
8
|
+
<li><%= error.full_message %></li>
|
|
9
|
+
<% end %>
|
|
10
|
+
</ul>
|
|
11
|
+
</div>
|
|
12
|
+
<% end %>
|
|
13
|
+
|
|
14
|
+
<div>
|
|
15
|
+
<%= form.label :title, style: "display: block" %>
|
|
16
|
+
<%= form.text_field :title %>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div>
|
|
20
|
+
<%= form.label :body, style: "display: block" %>
|
|
21
|
+
<%= form.text_area :body %>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<div>
|
|
25
|
+
<%= form.submit %>
|
|
26
|
+
</div>
|
|
27
|
+
<% end %>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<div id="<%= dom_id post %>">
|
|
2
|
+
<h3>posted by <%= post.user.name || post.user.email %></h4>
|
|
3
|
+
<h4><%= pluralize(post.views, 'view') %></h4>
|
|
4
|
+
|
|
5
|
+
<p>
|
|
6
|
+
<strong>Title:</strong>
|
|
7
|
+
<%= post.title %>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p>
|
|
11
|
+
<strong>Body:</strong>
|
|
12
|
+
<%= post.body %>
|
|
13
|
+
</p>
|
|
14
|
+
</div>
|