rails_app_generator 0.2.35 → 0.2.38
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/after_templates/addons/avo/_.rb +36 -24
- data/after_templates/addons/avo/app/avo/dashboards/dashboard.rb +12 -0
- data/after_templates/addons/avo/app/avo/resources/category_resource.rb +27 -0
- data/after_templates/addons/avo/app/avo/resources/post_resource.rb +25 -0
- data/after_templates/addons/avo/app/avo/resources/user_resource.rb +23 -0
- data/after_templates/addons/avo/app/controllers/home_controller.rb +4 -0
- data/after_templates/addons/avo/app/models/category.rb +7 -0
- data/after_templates/addons/avo/app/models/post.rb +9 -0
- data/after_templates/addons/avo/app/views/home/index.html.erb +1 -1
- data/after_templates/addons/avo/app/views/home/quick_signin.html.erb +3 -0
- data/after_templates/addons/avo/app/views/layouts/_footer.html.erb +0 -3
- data/after_templates/addons/avo/app/views/layouts/_navbar.html.erb +13 -8
- data/after_templates/addons/avo/app/views/layouts/application.html.erb +15 -2
- data/after_templates/addons/avo/config/initializers/avo.rb +105 -0
- data/after_templates/addons/avo/config/locales/en.yml +4 -0
- data/after_templates/addons/avo/db/seeds.rb +69 -12
- data/after_templates/addons/friendly_id/_.rb +68 -0
- data/after_templates/addons/friendly_id/app/controllers/home_controller.rb +5 -0
- data/after_templates/addons/friendly_id/app/controllers/posts_controller.rb +66 -0
- data/after_templates/addons/friendly_id/app/models/post.rb +16 -0
- data/after_templates/addons/friendly_id/app/views/home/index.html.erb +22 -0
- data/after_templates/addons/friendly_id/app/views/layouts/_footer.html.erb +0 -0
- data/after_templates/addons/friendly_id/app/views/layouts/_navbar.html.erb +3 -0
- data/after_templates/addons/friendly_id/app/views/layouts/application.html.erb +29 -0
- data/after_templates/addons/friendly_id/app/views/posts/show.html.erb +19 -0
- data/after_templates/addons/friendly_id/db/seeds.rb +47 -0
- data/docs/last_run/app_generator_class.json +25 -1
- data/docs/last_run/app_generator_data.json +9 -6
- data/docs/last_run/rails_options_class.json +25 -1
- data/docs/last_run/rails_options_data.json +9 -6
- data/lib/rails_app_generator/addons/avo.rb +8 -0
- data/lib/rails_app_generator/addons/friendly_id.rb +16 -0
- data/lib/rails_app_generator/addons/ransack.rb +34 -0
- data/lib/rails_app_generator/app_generator.rb +9 -1
- data/lib/rails_app_generator/rag_initializer.rb +2 -1
- data/lib/rails_app_generator/version.rb +1 -1
- data/package-lock.json +2 -2
- data/package.json +1 -1
- data/profiles/addons/avo.json +4 -2
- data/profiles/addons/friendly_id.json +14 -0
- data/templates/thor_task/profile/app/views/layouts/_navbar.html.erb +3 -3
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acc731854bb8ac95ec84859705ef81a8b9858802d9675a54dc02a6af5a9ee676
|
4
|
+
data.tar.gz: 3be6aedc699c1f8078aaa54e465658b17ed4e9b66f56e63832e187c0119e9afa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 520c0072f1fa27c043d4af71667cc486e67cae7606d19daa558482c6e7892322f1b7ab89d2ce685098d635b4d307d3f34ab035ce132b0eb131e625f2071f1f39
|
7
|
+
data.tar.gz: 57781bbb63ea180fb25aac7727d5ae0c88e8f2948d46e2d14635accb78a750c589462075cdfb2368f95eac8eb1da416150644370497e4c4c56b25b39a5bd5ee8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
## [0.2.37](https://github.com/klueless-io/rails_app_generator/compare/v0.2.36...v0.2.37) (2022-08-22)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* add friendly_id addon ([e6fc42e](https://github.com/klueless-io/rails_app_generator/commit/e6fc42e7d4ef017775c6b33850fb22aabc156ca5))
|
7
|
+
|
8
|
+
## [0.2.36](https://github.com/klueless-io/rails_app_generator/compare/v0.2.35...v0.2.36) (2022-08-22)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* update avo profile ([f02ee7f](https://github.com/klueless-io/rails_app_generator/commit/f02ee7f7e6e5e25842a023f210674d9602edfe58))
|
14
|
+
|
15
|
+
## [0.2.35](https://github.com/klueless-io/rails_app_generator/compare/v0.2.34...v0.2.35) (2022-08-20)
|
16
|
+
|
17
|
+
|
18
|
+
### Bug Fixes
|
19
|
+
|
20
|
+
* add image-processing addon ([3466708](https://github.com/klueless-io/rails_app_generator/commit/3466708e66cfc8da487f619f77516f863ef5cb46))
|
21
|
+
|
1
22
|
## [0.2.34](https://github.com/klueless-io/rails_app_generator/compare/v0.2.33...v0.2.34) (2022-08-19)
|
2
23
|
|
3
24
|
|
@@ -13,46 +13,58 @@ gac 'base rails 7 image created'
|
|
13
13
|
|
14
14
|
prepare_environment
|
15
15
|
|
16
|
-
add_controller('home', 'index')
|
17
|
-
|
18
|
-
route("root 'home#index'")
|
19
|
-
|
20
|
-
force_copy
|
21
|
-
|
22
|
-
directory "app/controllers"
|
23
|
-
directory "app/views/home"
|
24
|
-
directory "app/views/layouts"
|
25
|
-
template 'app/views/layouts/application.html.erb' , 'app/views/layouts/application.html.erb'
|
26
|
-
|
27
|
-
template 'db/seeds.rb' , 'db/seeds.rb'
|
28
|
-
|
29
16
|
after_bundle do
|
17
|
+
scaffolds
|
18
|
+
setup_customizations
|
30
19
|
setup_db
|
31
20
|
setup_avo
|
32
21
|
end
|
33
22
|
|
23
|
+
def scaffolds
|
24
|
+
add_scaffold_controller('users', 'name', 'email')
|
25
|
+
# add_scaffold('author', 'name', 'email', 'bio:text')
|
26
|
+
add_scaffold('category', 'title', 'description:text')
|
27
|
+
add_scaffold('post', 'title content:text', 'published:boolean', 'user:references', 'category:references')
|
28
|
+
add_scaffold('location', 'name', 'description:text') #, 'photo:file')
|
29
|
+
add_scaffold('room', 'name', 'description:text', 'location:references') #, 'photo:file'
|
30
|
+
add_scaffold('booking', 'user:references', 'room:references', 'booked_at:datetime', 'booked_for:integer')
|
31
|
+
end
|
32
|
+
|
33
|
+
def setup_customizations
|
34
|
+
route("root 'home#index'")
|
35
|
+
|
36
|
+
force_copy
|
37
|
+
|
38
|
+
add_controller('home', 'index', 'quick_signin')
|
39
|
+
|
40
|
+
directory "app/controllers"
|
41
|
+
directory "app/models"
|
42
|
+
directory "app/views"
|
43
|
+
template 'app/views/layouts/application.html.erb' , 'app/views/layouts/application.html.erb'
|
44
|
+
end
|
45
|
+
|
34
46
|
def setup_db
|
35
|
-
|
36
|
-
add_scaffold('category', 'title:string', 'description:text')
|
37
|
-
add_scaffold('post', 'title:string content:text', 'published:boolean', 'author:references', 'category:references')
|
38
|
-
add_scaffold('product', 'name', 'quantity:integer', 'price:decimal', 'author:references')
|
39
|
-
add_scaffold('location', 'name', 'description:text', 'photo:file')
|
40
|
-
add_scaffold('room', 'name', 'description:text', 'photo:file', 'location:references')
|
41
|
-
add_scaffold('booking', 'user:references', 'room:references', 'booked_at:timestamp', 'booked_for:number')
|
47
|
+
template 'db/seeds.rb' , 'db/seeds.rb'
|
42
48
|
|
43
49
|
db_migrate
|
44
50
|
db_seed
|
45
51
|
end
|
46
52
|
|
47
53
|
def setup_avo
|
48
|
-
generate('avo:install')
|
49
|
-
|
50
|
-
generate('avo:resource Post')
|
51
|
-
generate('avo:resource Author')
|
54
|
+
# generate('avo:install')
|
55
|
+
|
52
56
|
generate('avo:resource Category')
|
57
|
+
generate('avo:resource Post')
|
58
|
+
generate('avo:resource Location')
|
59
|
+
generate('avo:resource Room')
|
60
|
+
generate('avo:resource Booking')
|
53
61
|
generate('avo:resource User')
|
54
62
|
generate('avo:dashboard Dashboard')
|
55
63
|
|
64
|
+
directory "app/avo"
|
65
|
+
directory "config/initializers"
|
66
|
+
directory "config/locales"
|
67
|
+
|
56
68
|
# add devise support
|
57
69
|
gsub_file 'config/initializers/avo.rb', %(# config.current_user_method = {}), 'config.current_user_method = :current_user'
|
58
70
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Dashboard < Avo::Dashboards::BaseDashboard
|
2
|
+
self.id = "dashboard"
|
3
|
+
self.name = "Dashboard"
|
4
|
+
# self.description = "Tiny dashboard description"
|
5
|
+
# self.grid_cols = 3
|
6
|
+
# self.visible = -> do
|
7
|
+
# true
|
8
|
+
# end
|
9
|
+
|
10
|
+
# cards go here
|
11
|
+
# card UsersCount
|
12
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class CategoryResource < Avo::BaseResource
|
2
|
+
# tutorial (related category): https://youtu.be/WgNK-oINFww?t=328
|
3
|
+
|
4
|
+
self.title = :title
|
5
|
+
self.includes = []
|
6
|
+
|
7
|
+
self.search_query = ->(params:) do
|
8
|
+
scope
|
9
|
+
.ransack(id_eq: params[:q], name_cont: params[:q], title_cont: params[:q], description_cont: params[:q], m: "or")
|
10
|
+
.result(distinct: false)
|
11
|
+
end
|
12
|
+
|
13
|
+
field :id, as: :id
|
14
|
+
field :title, as: :text
|
15
|
+
field :excerpt, as: :text, only_on: :index
|
16
|
+
field :description, as: :textarea
|
17
|
+
|
18
|
+
# tutorial (computed field): https://youtu.be/WgNK-oINFww?t=514
|
19
|
+
field :posts_count, as: :text do |model|
|
20
|
+
model.posts.count
|
21
|
+
end
|
22
|
+
|
23
|
+
# tutorial (attach scope): https://youtu.be/WgNK-oINFww?t=423
|
24
|
+
field :posts, as: :has_many, attach_scope: -> {
|
25
|
+
query.where.not(category_id: parent.id).or(query.where(category_id: nil))
|
26
|
+
}
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class PostResource < Avo::BaseResource
|
2
|
+
# tutorial (title): https://youtu.be/WgNK-oINFww?t=301
|
3
|
+
self.title = :title
|
4
|
+
|
5
|
+
# tutorial (n+1): https://youtu.be/WgNK-oINFww?t=557
|
6
|
+
self.includes = [:category]
|
7
|
+
|
8
|
+
# tutorial (search): https://youtu.be/WgNK-oINFww?t=244
|
9
|
+
self.search_query = ->(params:) do
|
10
|
+
scope
|
11
|
+
.ransack(id_eq: params[:q], title_cont: params[:q], m: "or")
|
12
|
+
.result(distinct: false)
|
13
|
+
end
|
14
|
+
|
15
|
+
# tutorial (edit fields): https://youtu.be/WgNK-oINFww?t=133
|
16
|
+
field :id, as: :id
|
17
|
+
field :title, as: :text
|
18
|
+
field :content, as: :trix
|
19
|
+
|
20
|
+
# tutorial (read only fields): https://youtu.be/WgNK-oINFww?t=228
|
21
|
+
field :excerpt, as: :text, only_on: :index
|
22
|
+
|
23
|
+
# tutorial (related category): https://youtu.be/WgNK-oINFww?t=328
|
24
|
+
field :category, as: :belongs_to
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# tutorial (user resource): https://youtu.be/WgNK-oINFww?t=599
|
2
|
+
class UserResource < Avo::BaseResource
|
3
|
+
# https://docs.avohq.io/2.0/resources.html#devise-password-optional
|
4
|
+
# you need to fill in the password when creating a new user,
|
5
|
+
# but when editing a user you can leave the password field empty
|
6
|
+
self.devise_password_optional = true
|
7
|
+
|
8
|
+
# tutorial (better search experience): https://youtu.be/WgNK-oINFww?t=649
|
9
|
+
self.title = :email
|
10
|
+
self.includes = []
|
11
|
+
|
12
|
+
self.search_query = ->(params:) do
|
13
|
+
scope
|
14
|
+
.ransack(id_eq: params[:q], name_cont: params[:q], email_cont: params[:q], m: "or")
|
15
|
+
.result(distinct: false)
|
16
|
+
end
|
17
|
+
|
18
|
+
field :id, as: :id
|
19
|
+
field :email, as: :gravatar, link_to_resource: true, as_avatar: true
|
20
|
+
field :name, as: :text
|
21
|
+
field :email, as: :text, as_description: true
|
22
|
+
field :password, as: :text
|
23
|
+
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<h1>
|
1
|
+
<h1>I18n.t('application_name')</h1>
|
2
2
|
|
3
3
|
<p>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.</p>
|
@@ -1,8 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
<%= link_to 'Home', root_path %> |
|
2
|
+
<%= link_to 'Quick Sign In', home_quick_signin_path %> |
|
3
|
+
<%= link_to 'AVO', avo_path %>
|
4
|
+
(
|
5
|
+
<%= link_to 'Posts', posts_path, class: 'simple_scaffold' %> |
|
6
|
+
<%= link_to 'Categories', categories_path, class: 'simple_scaffold' %> |
|
7
|
+
<%= link_to 'Authors', users_path, class: 'simple_scaffold' %>
|
8
|
+
)
|
9
|
+
(
|
10
|
+
<%= link_to 'Locations', locations_path, class: 'simple_scaffold' %> |
|
11
|
+
<%= link_to 'Rooms', rooms_path, class: 'simple_scaffold' %> |
|
12
|
+
<%= link_to 'Bookings', bookings_path, class: 'simple_scaffold' %>
|
13
|
+
)
|
@@ -11,13 +11,26 @@
|
|
11
11
|
<%- else -%>
|
12
12
|
<%%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
13
13
|
<%- end -%>
|
14
|
+
<style>
|
15
|
+
.bold {
|
16
|
+
font-weight: bold;
|
17
|
+
}
|
18
|
+
.simple_scaffold {
|
19
|
+
color: #333333;
|
20
|
+
}
|
21
|
+
</style>
|
14
22
|
</head>
|
15
23
|
|
16
24
|
<body>
|
17
|
-
|
25
|
+
<header>
|
26
|
+
<%%= render 'layouts/navbar' %>
|
27
|
+
</header>
|
28
|
+
<hr>
|
18
29
|
<main>
|
19
30
|
<%%= yield %>
|
20
31
|
</main>
|
21
|
-
|
32
|
+
<footer>
|
33
|
+
<%%= render 'layouts/footer' %>
|
34
|
+
</footer>
|
22
35
|
</body>
|
23
36
|
</html>
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# For more information regaring these settings check out our docs https://docs.avohq.io
|
4
|
+
Avo.configure do |config|
|
5
|
+
## == Routing ==
|
6
|
+
config.root_path = '/admin'
|
7
|
+
|
8
|
+
# https://docs.avohq.io/2.0/customization.html
|
9
|
+
config.app_name = 'Custom Application'
|
10
|
+
config.id_links_to_resource = true
|
11
|
+
# config.resource_controls_placement = :left
|
12
|
+
|
13
|
+
# Where should the user be redirected when visting the `/avo` url
|
14
|
+
# config.home_path = nil
|
15
|
+
|
16
|
+
## == Licensing ==
|
17
|
+
config.license = 'pro' # change this to 'pro' when you add the license key
|
18
|
+
config.license_key = ENV['AVO_LICENSE_KEY']
|
19
|
+
|
20
|
+
## == Set the context ==
|
21
|
+
config.set_context do
|
22
|
+
# Return a context object that gets evaluated in Avo::ApplicationController
|
23
|
+
end
|
24
|
+
|
25
|
+
## == Authentication ==
|
26
|
+
config.current_user_method = :current_user
|
27
|
+
# config.authenticate_with = {}
|
28
|
+
|
29
|
+
## == Authorization ==
|
30
|
+
# config.authorization_methods = {
|
31
|
+
# index: 'index?',
|
32
|
+
# show: 'show?',
|
33
|
+
# edit: 'edit?',
|
34
|
+
# new: 'new?',
|
35
|
+
# update: 'update?',
|
36
|
+
# create: 'create?',
|
37
|
+
# destroy: 'destroy?',
|
38
|
+
# }
|
39
|
+
# config.raise_error_on_missing_policy = false
|
40
|
+
|
41
|
+
## == Localization ==
|
42
|
+
# config.locale = 'en-US'
|
43
|
+
|
44
|
+
## == Customization ==
|
45
|
+
# config.app_name = 'Avocadelicious'
|
46
|
+
# config.timezone = 'UTC'
|
47
|
+
# config.currency = 'USD'
|
48
|
+
# config.per_page = 24
|
49
|
+
# config.per_page_steps = [12, 24, 48, 72]
|
50
|
+
# config.via_per_page = 8
|
51
|
+
# config.default_view_type = :table
|
52
|
+
# config.hide_layout_when_printing = false
|
53
|
+
# config.id_links_to_resource = false
|
54
|
+
# config.full_width_container = false
|
55
|
+
# config.full_width_index_view = false
|
56
|
+
# config.cache_resources_on_index_view = true
|
57
|
+
# config.search_debounce = 300
|
58
|
+
# config.view_component_path = "app/components"
|
59
|
+
# config.display_license_request_timeout_error = true
|
60
|
+
# config.disabled_features = []
|
61
|
+
|
62
|
+
## == Breadcrumbs ==
|
63
|
+
# config.display_breadcrumbs = true
|
64
|
+
config.set_initial_breadcrumbs do
|
65
|
+
add_breadcrumb "Home", '/admin'
|
66
|
+
end
|
67
|
+
|
68
|
+
## == Menus ==
|
69
|
+
config.main_menu = -> {
|
70
|
+
section "Dashboards", icon: "dashboards" do
|
71
|
+
all_dashboards
|
72
|
+
end
|
73
|
+
|
74
|
+
section "Resources", icon: "resources" do
|
75
|
+
group "Blog" do
|
76
|
+
resource :post
|
77
|
+
# resource :comment
|
78
|
+
resource :category
|
79
|
+
resource :author
|
80
|
+
end
|
81
|
+
|
82
|
+
group "Reservations" do # , collapsable: true, collapsed: true
|
83
|
+
resource :location
|
84
|
+
resource :room
|
85
|
+
resource :booking
|
86
|
+
end
|
87
|
+
|
88
|
+
group "Admin" do
|
89
|
+
resource :user
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
section "Tools", icon: "tools" do
|
94
|
+
all_tools
|
95
|
+
end
|
96
|
+
|
97
|
+
section I18n.t('admin.external_links'), icon: "heroicons/outline/link", collapsable: true, collapsed: true do
|
98
|
+
link 'Appy Dave', path: 'https://appydave.com', target: :_blank
|
99
|
+
link 'Klueless', path: 'https://klueless.io/', target: :_blank
|
100
|
+
end
|
101
|
+
}
|
102
|
+
config.profile_menu = -> {
|
103
|
+
link "Profile", path: "/admin/profile", icon: "user-circle"
|
104
|
+
}
|
105
|
+
end
|
@@ -10,6 +10,46 @@ def fake_category
|
|
10
10
|
]
|
11
11
|
end
|
12
12
|
|
13
|
+
def avatar_emails
|
14
|
+
[
|
15
|
+
'ben@ben.com',
|
16
|
+
'david@hey.com',
|
17
|
+
'adrian@adrianthedev.com',
|
18
|
+
'david@ideasmen.com.au'
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def email_domain
|
24
|
+
[
|
25
|
+
'gmail.com',
|
26
|
+
'outlook.com',
|
27
|
+
'yahoo.com',
|
28
|
+
'hotmail.com',
|
29
|
+
'aol.com',
|
30
|
+
'mail.com',
|
31
|
+
].sample
|
32
|
+
end
|
33
|
+
|
34
|
+
def common_names
|
35
|
+
[
|
36
|
+
'Ben',
|
37
|
+
'John',
|
38
|
+
'James',
|
39
|
+
'Robert',
|
40
|
+
'Michael',
|
41
|
+
'William',
|
42
|
+
'Mary',
|
43
|
+
'Patricia',
|
44
|
+
'Linda',
|
45
|
+
'Barbara',
|
46
|
+
'Elizabeth',
|
47
|
+
'Jennifer',
|
48
|
+
'Maria',
|
49
|
+
'Susan',
|
50
|
+
]
|
51
|
+
end
|
52
|
+
|
13
53
|
def fake_title
|
14
54
|
[
|
15
55
|
'Fundamentals of Wavelets',
|
@@ -108,25 +148,42 @@ def fake_title
|
|
108
148
|
].sample
|
109
149
|
end
|
110
150
|
|
111
|
-
|
112
|
-
|
151
|
+
User.find_or_create_by(email: "admin@admin.com") do |user|
|
152
|
+
user.name = 'Admin'
|
153
|
+
user.password = 'password'
|
154
|
+
user.role = :admin
|
113
155
|
end
|
114
156
|
|
157
|
+
common_names.each do |first_name|
|
158
|
+
last_name = Faker::Name.last_name
|
159
|
+
email = Faker::Internet.email(name: first_name.downcase, domain: email_domain)
|
160
|
+
User.create!(name: "#{first_name} #{last_name}", email: email, password: 'password', role: :user)
|
161
|
+
end
|
162
|
+
|
163
|
+
avatar_emails.each do |email|
|
164
|
+
first_name = email.split('@').first
|
165
|
+
last_name = Faker::Name.last_name
|
166
|
+
User.create!(name: "#{first_name} #{last_name}", email: email, password: 'password', role: :user)
|
167
|
+
end
|
168
|
+
# bio: Faker::Lorem.words(number: 5).join(' ')
|
169
|
+
|
115
170
|
fake_category.each do |category|
|
116
171
|
Category.create!(title: category, description: Faker::Lorem.sentence)
|
117
172
|
end
|
118
173
|
|
119
|
-
|
174
|
+
40.times do
|
120
175
|
Post.create!(title: fake_title,
|
121
|
-
content:
|
176
|
+
content: Faker::Lorem.sentences(number: 5).join('<br />'),
|
122
177
|
published: Faker::Boolean.boolean(true_ratio: 0.6),
|
123
|
-
|
178
|
+
category: Category.all.sample,
|
179
|
+
author: User.all.sample)
|
124
180
|
end
|
125
181
|
|
126
|
-
200.times do
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
182
|
+
# 200.times do
|
183
|
+
# Product.create!(
|
184
|
+
# name: Faker::Name.name,
|
185
|
+
# quantity: Faker::Number.number(digits: 2),
|
186
|
+
# price: Faker::Number.decimal(l_digits: 4),
|
187
|
+
# author: Author.all.sample
|
188
|
+
# )
|
189
|
+
# end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# FriendlyId provides slugging and permalink support for Active Record. It lets you create pretty URLs and work with human-friendly strings as if they were numeric ids.
|
4
|
+
#
|
5
|
+
# exe/rag addons/friendly_id
|
6
|
+
|
7
|
+
self.local_template_path = File.dirname(__FILE__)
|
8
|
+
|
9
|
+
gac 'base rails 7 image created'
|
10
|
+
|
11
|
+
prepare_environment
|
12
|
+
|
13
|
+
after_bundle do
|
14
|
+
scaffolds
|
15
|
+
setup_customizations
|
16
|
+
setup_db
|
17
|
+
end
|
18
|
+
|
19
|
+
def scaffolds
|
20
|
+
add_scaffold('post', 'title', 'category', 'body:text', 'slug:uniq')
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_customizations
|
24
|
+
route("root 'home#index'")
|
25
|
+
|
26
|
+
force_copy
|
27
|
+
|
28
|
+
add_controller('home', 'index')
|
29
|
+
|
30
|
+
directory "app/controllers"
|
31
|
+
directory "app/models"
|
32
|
+
directory "app/views"
|
33
|
+
template 'app/views/layouts/application.html.erb' , 'app/views/layouts/application.html.erb'
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup_db
|
37
|
+
template 'db/seeds.rb' , 'db/seeds.rb'
|
38
|
+
|
39
|
+
db_migrate
|
40
|
+
db_seed
|
41
|
+
end
|
42
|
+
|
43
|
+
# Other template command examples
|
44
|
+
# prepare_environment
|
45
|
+
# bundle_install
|
46
|
+
# css_install('tailwind')
|
47
|
+
# rails_command('db:migrate')
|
48
|
+
# rails_command('db:migrate')
|
49
|
+
# bundle_add('hotwire-rails')
|
50
|
+
# rails_command('hotwire:install')
|
51
|
+
# run('bin/importmap pin sortablejs')
|
52
|
+
# run('npm install daisyui')
|
53
|
+
# rubocop
|
54
|
+
#
|
55
|
+
# directory 'app/assets/images'
|
56
|
+
# create_file 'app/assets/stylesheets/custom-bootstrap-import.scss' , read_template('custom-bootstrap-import.scss')
|
57
|
+
# append_to_file 'app/assets/config/manifest.js' , read_template('manifest.js')
|
58
|
+
# insert_into_file 'app/views/layouts/application.html.erb', read_template('application.html.erb'),
|
59
|
+
# before: %( <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>)
|
60
|
+
# gsub_file 'app/views/layouts/application.html.erb', %(container mx-auto mt-28 px-5 flex), 'container mx-auto px-5'
|
61
|
+
# template 'home.css', 'app/assets/stylesheets/home.css'
|
62
|
+
#
|
63
|
+
# add_controller('page', 'benefits', 'faq', 'terms', 'privacy', '--skip-routes')
|
64
|
+
# route(<<-'RUBY')
|
65
|
+
# PageController.action_methods.each do |action|
|
66
|
+
# get "/#{action}", to: "page##{action}", as: "page_#{action}"
|
67
|
+
# end
|
68
|
+
# RUBY
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class PostsController < ApplicationController
|
2
|
+
before_action :set_post, only: %i[ edit update destroy ]
|
3
|
+
|
4
|
+
def index
|
5
|
+
@posts = Post.all
|
6
|
+
end
|
7
|
+
|
8
|
+
# GET /posts/1 or /posts/some-friendly-slug
|
9
|
+
def show
|
10
|
+
@post = Post.friendly.find(params[:id])
|
11
|
+
@friendly = @post.slug == params[:id]
|
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
|
+
|
24
|
+
respond_to do |format|
|
25
|
+
if @post.save
|
26
|
+
format.html { redirect_to post_url(@post), notice: "Post was successfully created." }
|
27
|
+
format.json { render :show, status: :created, location: @post }
|
28
|
+
else
|
29
|
+
format.html { render :new, status: :unprocessable_entity }
|
30
|
+
format.json { render json: @post.errors, status: :unprocessable_entity }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def update
|
36
|
+
respond_to do |format|
|
37
|
+
if @post.update(post_params)
|
38
|
+
format.html { redirect_to post_url(@post), notice: "Post was successfully updated." }
|
39
|
+
format.json { render :show, status: :ok, location: @post }
|
40
|
+
else
|
41
|
+
format.html { render :edit, status: :unprocessable_entity }
|
42
|
+
format.json { render json: @post.errors, status: :unprocessable_entity }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def destroy
|
48
|
+
@post.destroy
|
49
|
+
|
50
|
+
respond_to do |format|
|
51
|
+
format.html { redirect_to posts_url, notice: "Post was successfully destroyed." }
|
52
|
+
format.json { head :no_content }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
# Use callbacks to share common setup or constraints between actions.
|
58
|
+
def set_post
|
59
|
+
@post = Post.find(params[:id])
|
60
|
+
end
|
61
|
+
|
62
|
+
# Only allow a list of trusted parameters through.
|
63
|
+
def post_params
|
64
|
+
params.require(:post).permit(:title, :body)
|
65
|
+
end
|
66
|
+
end
|