godmin 1.3.1 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.codeclimate.yml +0 -2
- data/.gitignore +1 -0
- data/.travis.yml +9 -10
- data/Appraisals +4 -4
- data/CHANGELOG.md +84 -2
- data/Gemfile +1 -2
- data/README.md +119 -10
- data/Rakefile +2 -2
- data/app/views/godmin/resource/_breadcrumb.html.erb +12 -24
- data/app/views/godmin/resource/_breadcrumb_actions.html.erb +41 -0
- data/app/views/godmin/resource/_button_actions.html.erb +1 -1
- data/app/views/godmin/resource/_pagination.html.erb +4 -4
- data/app/views/godmin/resource/_table.html.erb +3 -0
- data/app/views/godmin/resource/columns/_actions.html.erb +4 -4
- data/app/views/godmin/resource/show.html.erb +1 -1
- data/config/locales/en.yml +2 -0
- data/config/locales/pt-BR.yml +2 -0
- data/config/locales/sv.yml +2 -0
- data/gemfiles/rails_5.gemfile +3 -4
- data/gemfiles/rails_6.gemfile +8 -0
- data/godmin.gemspec +18 -16
- data/lib/generators/godmin/resource/resource_generator.rb +7 -1
- data/lib/generators/godmin/resource/templates/resource_model.rb +4 -0
- data/lib/godmin/application_controller.rb +10 -11
- data/lib/godmin/authentication.rb +11 -11
- data/lib/godmin/authentication/sessions_controller.rb +2 -1
- data/lib/godmin/authorization.rb +34 -14
- data/lib/godmin/engine_wrapper.rb +10 -1
- data/lib/godmin/generators/base.rb +4 -4
- data/lib/godmin/generators/named_base.rb +4 -4
- data/lib/godmin/helpers/application.rb +3 -3
- data/lib/godmin/helpers/batch_actions.rb +1 -1
- data/lib/godmin/helpers/forms.rb +5 -1
- data/lib/godmin/paginator.rb +12 -4
- data/lib/godmin/resolver.rb +20 -5
- data/lib/godmin/resources/resource_controller.rb +24 -5
- data/lib/godmin/resources/resource_controller/batch_actions.rb +1 -1
- data/lib/godmin/resources/resource_service.rb +8 -7
- data/lib/godmin/resources/resource_service/associations.rb +23 -0
- data/lib/godmin/version.rb +1 -1
- data/template.rb +17 -3
- data/test/dummy/admin/app/controllers/admin/authorized_articles_controller.rb +29 -0
- data/test/dummy/admin/app/models/admin/article.rb +4 -0
- data/test/dummy/admin/app/models/admin/magazine.rb +4 -0
- data/test/dummy/admin/app/policies/admin/article_policy.rb +11 -0
- data/test/dummy/admin/app/policies/admin/magazine_policy.rb +4 -0
- data/test/dummy/admin/app/views/admin/shared/_navigation.html.erb +5 -0
- data/test/dummy/admin/config/routes.rb +1 -0
- data/test/dummy/app/assets/config/manifest.js +4 -0
- data/test/dummy/app/controllers/another_admin_sessions_controller.rb +8 -0
- data/test/dummy/app/controllers/comments_controller.rb +3 -0
- data/test/dummy/app/models/another_admin_user.rb +7 -0
- data/test/dummy/app/models/article.rb +1 -0
- data/test/dummy/app/models/comment.rb +7 -0
- data/test/dummy/app/models/magazine.rb +2 -0
- data/test/dummy/app/services/article_service.rb +2 -0
- data/test/dummy/app/services/comment_service.rb +7 -0
- data/test/dummy/bin/rails +1 -1
- data/test/dummy/config/application.rb +2 -14
- data/test/dummy/config/locales/en.yml +9 -0
- data/test/dummy/config/routes.rb +6 -1
- data/test/dummy/db/migrate/20150717121532_create_articles.rb +1 -1
- data/test/dummy/db/migrate/20150907133753_create_admin_users.rb +1 -1
- data/test/dummy/db/migrate/20160713134238_create_comment.rb +9 -0
- data/test/dummy/db/migrate/20170207081043_create_another_admin_user.rb +10 -0
- data/test/dummy/db/migrate/20210519215502_create_magazines.rb +9 -0
- data/test/dummy/db/schema.rb +38 -16
- data/test/fakes/article.rb +1 -1
- data/test/fakes/article_service.rb +3 -7
- data/test/generators/resource_generator_test.rb +78 -0
- data/test/integration/authentication_test.rb +8 -0
- data/test/integration/authorization_test.rb +13 -0
- data/test/integration/nested_resources_test.rb +47 -0
- data/test/test_helper.rb +1 -4
- data/test/{lib/godmin → unit}/engine_wrapper_test.rb +1 -1
- data/test/{lib/godmin → unit}/helpers/filters_test.rb +0 -0
- data/test/{lib/godmin → unit}/paginator_test.rb +11 -0
- data/test/{lib/godmin → unit}/resolver_test.rb +0 -0
- data/test/{lib/godmin → unit}/resources/resource_service/batch_actions_test.rb +1 -1
- data/test/{lib/godmin → unit}/resources/resource_service/filters_test.rb +1 -1
- data/test/{lib/godmin → unit}/resources/resource_service/ordering_test.rb +1 -1
- data/test/{lib/godmin → unit}/resources/resource_service/pagination_test.rb +0 -0
- data/test/{lib/godmin → unit}/resources/resource_service/scopes_test.rb +0 -0
- data/test/{lib/godmin → unit}/resources/resource_service_test.rb +0 -0
- metadata +175 -108
- data/gemfiles/rails_4.gemfile +0 -9
- data/lib/godmin/authorization/policy_finder.rb +0 -31
- data/lib/tasks/godmin_tasks.rake +0 -4
- data/test/lib/godmin/policy_finder_test.rb +0 -55
@@ -40,8 +40,17 @@ module Godmin
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
# Some gymnastics because the `parents` function is slated for deprecation
|
44
|
+
# and being replaced by `module_parents` and we don't want to clutter our
|
45
|
+
# log with a million warnings
|
46
|
+
def parents_of(controller)
|
47
|
+
return controller.module_parents if controller.respond_to?(:module_parents)
|
48
|
+
|
49
|
+
controller.parents
|
50
|
+
end
|
51
|
+
|
43
52
|
def find_engine_module(controller)
|
44
|
-
controller.
|
53
|
+
parents_of(controller).find do |parent|
|
45
54
|
parent.respond_to?(:use_relative_model_naming?) && parent.use_relative_model_naming?
|
46
55
|
end
|
47
56
|
end
|
@@ -4,7 +4,7 @@ module Godmin
|
|
4
4
|
module Generators
|
5
5
|
class Base < Rails::Generators::Base
|
6
6
|
def self.source_paths
|
7
|
-
%w
|
7
|
+
%w[authentication install policy resource].map do |path|
|
8
8
|
File.expand_path("../../../generators/godmin/#{path}/templates", __FILE__)
|
9
9
|
end
|
10
10
|
end
|
@@ -12,15 +12,15 @@ module Godmin
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def namespace
|
15
|
-
@
|
15
|
+
@_namespace ||= Rails::Generators.namespace
|
16
16
|
end
|
17
17
|
|
18
18
|
def namespaced?
|
19
|
-
@
|
19
|
+
@_namespaced ||= namespace.present?
|
20
20
|
end
|
21
21
|
|
22
22
|
def namespaced_path
|
23
|
-
@
|
23
|
+
@_namespaced_path ||= begin
|
24
24
|
if namespaced?
|
25
25
|
namespace.name.split("::").map(&:underscore)
|
26
26
|
else
|
@@ -8,7 +8,7 @@ module Godmin
|
|
8
8
|
private
|
9
9
|
|
10
10
|
def full_class_name
|
11
|
-
if
|
11
|
+
if namespaced?
|
12
12
|
"#{namespace}::#{class_name}"
|
13
13
|
else
|
14
14
|
class_name
|
@@ -16,15 +16,15 @@ module Godmin
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def class_name
|
19
|
-
@
|
19
|
+
@_class_name ||= name.classify
|
20
20
|
end
|
21
21
|
|
22
22
|
def class_path
|
23
|
-
@
|
23
|
+
@_class_path ||= namespaced_path + name.classify.deconstantize.split("::").map(&:underscore)
|
24
24
|
end
|
25
25
|
|
26
26
|
def file_name
|
27
|
-
@
|
27
|
+
@_file_name ||= class_name.demodulize.underscore
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -4,17 +4,17 @@ module Godmin
|
|
4
4
|
# Renders the provided partial with locals if it exists, otherwise
|
5
5
|
# yields the given block. The lookup context call is cached for
|
6
6
|
# each partial.
|
7
|
-
def partial_override(partial, locals = {})
|
7
|
+
def partial_override(partial, locals = {}, &block)
|
8
8
|
@_partial_override ||= {}
|
9
9
|
|
10
|
-
|
10
|
+
unless @_partial_override.key?(partial)
|
11
11
|
@_partial_override[partial] = lookup_context.exists?(partial, nil, true)
|
12
12
|
end
|
13
13
|
|
14
14
|
if @_partial_override[partial]
|
15
15
|
render partial: partial, locals: locals
|
16
16
|
else
|
17
|
-
|
17
|
+
capture(&block)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
data/lib/godmin/helpers/forms.rb
CHANGED
@@ -2,7 +2,11 @@ module Godmin
|
|
2
2
|
module Helpers
|
3
3
|
module Forms
|
4
4
|
def form_for(record, options = {}, &block)
|
5
|
-
super(record, {
|
5
|
+
super(record, {
|
6
|
+
url: [*@resource_parents, record],
|
7
|
+
builder: FormBuilders::FormBuilder,
|
8
|
+
inline_errors: false
|
9
|
+
}.merge(options), &block)
|
6
10
|
end
|
7
11
|
end
|
8
12
|
end
|
data/lib/godmin/paginator.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module Godmin
|
2
2
|
class Paginator
|
3
|
-
WINDOW_SIZE = 7
|
3
|
+
WINDOW_SIZE = 7
|
4
4
|
|
5
5
|
attr_reader :per_page, :current_page
|
6
6
|
|
7
7
|
def initialize(resources, per_page: 25, current_page: nil)
|
8
|
-
@resources
|
9
|
-
@per_page
|
8
|
+
@resources = resources
|
9
|
+
@per_page = per_page
|
10
10
|
@current_page = current_page ? current_page.to_i : 1
|
11
11
|
end
|
12
12
|
|
@@ -35,7 +35,15 @@ module Godmin
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def total_resources
|
38
|
-
@total_resources ||=
|
38
|
+
@total_resources ||= begin
|
39
|
+
count = @resources.count
|
40
|
+
|
41
|
+
if count.respond_to?(:count)
|
42
|
+
count.count
|
43
|
+
else
|
44
|
+
count
|
45
|
+
end
|
46
|
+
end
|
39
47
|
end
|
40
48
|
|
41
49
|
private
|
data/lib/godmin/resolver.rb
CHANGED
@@ -16,15 +16,30 @@ module Godmin
|
|
16
16
|
@engine_wrapper = engine_wrapper
|
17
17
|
end
|
18
18
|
|
19
|
+
# This function is for Rails 6 and up since the `find_templates` function
|
20
|
+
# is deprecated. It does the same thing, just a little differently. It's
|
21
|
+
# not being run by versions previous to Rails 6.
|
22
|
+
def _find_all(name, prefix, partial, details, key, locals)
|
23
|
+
templates = []
|
24
|
+
|
25
|
+
template_paths(prefix).each do |p|
|
26
|
+
break if templates.present?
|
27
|
+
|
28
|
+
path = Path.build(name, "#{@path}/#{p}", partial)
|
29
|
+
templates = query(path, details, details[:formats], locals, cache: !!key)
|
30
|
+
end
|
31
|
+
|
32
|
+
templates
|
33
|
+
end
|
34
|
+
|
35
|
+
# This is how we find templates in Rails 5 and below.
|
19
36
|
def find_templates(name, prefix, *args)
|
20
37
|
templates = []
|
21
38
|
|
22
39
|
template_paths(prefix).each do |path|
|
23
|
-
if templates.present?
|
24
|
-
|
25
|
-
|
26
|
-
templates = super(name, path, *args)
|
27
|
-
end
|
40
|
+
break if templates.present?
|
41
|
+
|
42
|
+
templates = super(name, path, *args)
|
28
43
|
end
|
29
44
|
|
30
45
|
templates
|
@@ -17,6 +17,7 @@ module Godmin
|
|
17
17
|
|
18
18
|
before_action :set_resource_service
|
19
19
|
before_action :set_resource_class
|
20
|
+
before_action :set_resource_parents
|
20
21
|
before_action :set_resources, only: :index
|
21
22
|
before_action :set_resource, only: [:show, :new, :edit, :create, :update, :destroy]
|
22
23
|
end
|
@@ -83,6 +84,10 @@ module Godmin
|
|
83
84
|
@resource_class = resource_class
|
84
85
|
end
|
85
86
|
|
87
|
+
def set_resource_parents
|
88
|
+
@resource_parents = resource_parents
|
89
|
+
end
|
90
|
+
|
86
91
|
def set_resources
|
87
92
|
@resources = resources
|
88
93
|
authorize(@resources) if authorization_enabled?
|
@@ -98,17 +103,31 @@ module Godmin
|
|
98
103
|
end
|
99
104
|
|
100
105
|
def resource_service
|
106
|
+
resource_service = resource_service_class.new
|
107
|
+
|
101
108
|
if authentication_enabled?
|
102
|
-
|
103
|
-
|
104
|
-
|
109
|
+
resource_service.options[:admin_user] = admin_user
|
110
|
+
end
|
111
|
+
|
112
|
+
if resource_parents.present?
|
113
|
+
resource_service.options[:resource_parent] = resource_parents.last
|
105
114
|
end
|
115
|
+
|
116
|
+
resource_service
|
106
117
|
end
|
107
118
|
|
108
119
|
def resource_class
|
109
120
|
@resource_service.resource_class
|
110
121
|
end
|
111
122
|
|
123
|
+
def resource_parents
|
124
|
+
params.to_unsafe_h.each_with_object([]) do |(name, value), parents|
|
125
|
+
if name =~ /(.+)_id$/
|
126
|
+
parents << $1.classify.constantize.find(value)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
112
131
|
def resources
|
113
132
|
@resource_service.resources(params)
|
114
133
|
end
|
@@ -151,11 +170,11 @@ module Godmin
|
|
151
170
|
end
|
152
171
|
|
153
172
|
def redirect_after_save
|
154
|
-
@resource
|
173
|
+
[*@resource_parents, @resource]
|
155
174
|
end
|
156
175
|
|
157
176
|
def redirect_after_destroy
|
158
|
-
resource_class.model_name.route_key.to_sym
|
177
|
+
[*@resource_parents, resource_class.model_name.route_key.to_sym]
|
159
178
|
end
|
160
179
|
|
161
180
|
def redirect_flash_message
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "godmin/resources/resource_service/associations"
|
1
2
|
require "godmin/resources/resource_service/batch_actions"
|
2
3
|
require "godmin/resources/resource_service/filters"
|
3
4
|
require "godmin/resources/resource_service/ordering"
|
@@ -9,6 +10,7 @@ module Godmin
|
|
9
10
|
module ResourceService
|
10
11
|
extend ActiveSupport::Concern
|
11
12
|
|
13
|
+
include Associations
|
12
14
|
include BatchActions
|
13
15
|
include Filters
|
14
16
|
include Ordering
|
@@ -21,17 +23,16 @@ module Godmin
|
|
21
23
|
@options = options
|
22
24
|
end
|
23
25
|
|
24
|
-
# TODO: should this raise its own error?
|
25
26
|
def resource_class
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
def resource_class_name
|
30
|
-
self.class.name.demodulize.chomp("Service")
|
27
|
+
self.class.name.chomp("Service").constantize
|
31
28
|
end
|
32
29
|
|
33
30
|
def resources_relation
|
34
|
-
|
31
|
+
if options[:resource_parent].present?
|
32
|
+
resource_class.where(options[:resource_parent].class.name.underscore => options[:resource_parent])
|
33
|
+
else
|
34
|
+
resource_class.all
|
35
|
+
end
|
35
36
|
end
|
36
37
|
|
37
38
|
def resources(params)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Godmin
|
2
|
+
module Resources
|
3
|
+
module ResourceService
|
4
|
+
module Associations
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
delegate :has_many_map, to: "self.class"
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def has_many_map
|
11
|
+
@has_many_map ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def has_many(attr, options = {})
|
15
|
+
has_many_map[attr] = {
|
16
|
+
class_name: attr.to_s.singularize.classify
|
17
|
+
}.merge(options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/godmin/version.rb
CHANGED
data/template.rb
CHANGED
@@ -3,7 +3,7 @@ require "active_support/all"
|
|
3
3
|
def install_standalone
|
4
4
|
set_ruby_version
|
5
5
|
|
6
|
-
gem "godmin", "1.
|
6
|
+
gem "godmin", "1.5.0"
|
7
7
|
|
8
8
|
after_bundle do
|
9
9
|
create_database
|
@@ -21,6 +21,7 @@ def install_standalone
|
|
21
21
|
modify_author_service
|
22
22
|
modify_article_controller
|
23
23
|
modify_article_service
|
24
|
+
modify_readme
|
24
25
|
|
25
26
|
migrate_and_seed
|
26
27
|
end
|
@@ -36,7 +37,7 @@ def install_engine
|
|
36
37
|
|
37
38
|
inject_into_file "admin/admin.gemspec", before: /^end/ do
|
38
39
|
<<-END.strip_heredoc.indent(2)
|
39
|
-
s.add_dependency "godmin", "~> 1.
|
40
|
+
s.add_dependency "godmin", "~> 1.5.0"
|
40
41
|
END
|
41
42
|
end
|
42
43
|
|
@@ -64,6 +65,7 @@ def install_engine
|
|
64
65
|
modify_author_service("admin")
|
65
66
|
modify_article_controller("admin")
|
66
67
|
modify_article_service("admin")
|
68
|
+
modify_readme
|
67
69
|
|
68
70
|
migrate_and_seed
|
69
71
|
end
|
@@ -71,7 +73,7 @@ end
|
|
71
73
|
|
72
74
|
def set_ruby_version
|
73
75
|
prepend_to_file "Gemfile" do
|
74
|
-
"ruby '2.
|
76
|
+
"ruby '2.3.5'\n"
|
75
77
|
end
|
76
78
|
end
|
77
79
|
|
@@ -308,6 +310,18 @@ def modify_author_service(namespace = nil)
|
|
308
310
|
end
|
309
311
|
end
|
310
312
|
|
313
|
+
def modify_readme
|
314
|
+
readme_file = "README.md"
|
315
|
+
run "rm #{readme_file}"
|
316
|
+
readme_text = <<~README
|
317
|
+
# README
|
318
|
+
|
319
|
+
This is the source code for a demo application of the [Godmin](https://github.com/varvet/godmin) admin framework for Rails.
|
320
|
+
It is generated by running `rake sandbox:deploy` inside the Godmin repo.
|
321
|
+
README
|
322
|
+
File.open(readme_file, 'w') { |file| file.write(readme_text) }
|
323
|
+
end
|
324
|
+
|
311
325
|
def migrate_and_seed
|
312
326
|
rake("db:migrate")
|
313
327
|
rake("db:seed")
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_dependency "admin/articles_controller"
|
2
|
+
|
3
|
+
module Admin
|
4
|
+
class AuthorizedArticlesController < ArticlesController
|
5
|
+
include Godmin::Authorization
|
6
|
+
|
7
|
+
def admin_user
|
8
|
+
"admin"
|
9
|
+
end
|
10
|
+
|
11
|
+
def new
|
12
|
+
# The following calls to #policy are to check that the Authorization
|
13
|
+
# module can handle various different scenarios:
|
14
|
+
policy(Magazine).index?
|
15
|
+
policy(::Magazine).index?
|
16
|
+
policy(Magazine.new).index?
|
17
|
+
policy(Magazine.all).index?
|
18
|
+
policy(Admin::Magazine).index?
|
19
|
+
policy(Admin::Magazine.new).index?
|
20
|
+
policy(Admin::Magazine.where(name: "name")).index?
|
21
|
+
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def resource_service_class
|
26
|
+
Admin::ArticleService
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|