godmin 1.3.0 → 2.1.0

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 (84) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +0 -2
  3. data/.gitignore +1 -0
  4. data/.travis.yml +7 -15
  5. data/Appraisals +4 -4
  6. data/CHANGELOG.md +83 -2
  7. data/Gemfile +1 -2
  8. data/README.md +74 -9
  9. data/Rakefile +2 -10
  10. data/app/views/godmin/resource/_breadcrumb.html.erb +12 -24
  11. data/app/views/godmin/resource/_breadcrumb_actions.html.erb +41 -0
  12. data/app/views/godmin/resource/_button_actions.html.erb +1 -1
  13. data/app/views/godmin/resource/_table.html.erb +3 -0
  14. data/app/views/godmin/resource/columns/_actions.html.erb +4 -4
  15. data/app/views/godmin/resource/show.html.erb +1 -1
  16. data/config/locales/en.yml +2 -0
  17. data/config/locales/pt-BR.yml +2 -0
  18. data/config/locales/sv.yml +2 -0
  19. data/gemfiles/rails_5.gemfile +3 -4
  20. data/gemfiles/rails_6.gemfile +8 -0
  21. data/godmin.gemspec +18 -16
  22. data/lib/generators/godmin/resource/resource_generator.rb +7 -1
  23. data/lib/generators/godmin/resource/templates/resource_model.rb +4 -0
  24. data/lib/godmin/application_controller.rb +10 -11
  25. data/lib/godmin/authentication.rb +11 -11
  26. data/lib/godmin/authentication/sessions_controller.rb +2 -1
  27. data/lib/godmin/authorization.rb +6 -20
  28. data/lib/godmin/engine_wrapper.rb +10 -1
  29. data/lib/godmin/generators/base.rb +4 -4
  30. data/lib/godmin/generators/named_base.rb +4 -4
  31. data/lib/godmin/helpers/application.rb +3 -3
  32. data/lib/godmin/helpers/batch_actions.rb +1 -1
  33. data/lib/godmin/helpers/forms.rb +5 -1
  34. data/lib/godmin/paginator.rb +12 -4
  35. data/lib/godmin/resolver.rb +23 -5
  36. data/lib/godmin/resources/resource_controller.rb +24 -5
  37. data/lib/godmin/resources/resource_controller/batch_actions.rb +1 -1
  38. data/lib/godmin/resources/resource_service.rb +8 -7
  39. data/lib/godmin/resources/resource_service/associations.rb +23 -0
  40. data/lib/godmin/version.rb +1 -1
  41. data/template.rb +42 -7
  42. data/test/dummy/admin/app/controllers/admin/authorized_articles_controller.rb +15 -0
  43. data/test/dummy/admin/app/models/admin/article.rb +4 -0
  44. data/test/dummy/admin/app/policies/admin/article_policy.rb +7 -0
  45. data/test/dummy/admin/config/routes.rb +1 -0
  46. data/test/dummy/app/assets/config/manifest.js +4 -0
  47. data/test/dummy/app/controllers/another_admin_sessions_controller.rb +8 -0
  48. data/test/dummy/app/controllers/comments_controller.rb +3 -0
  49. data/test/dummy/app/models/another_admin_user.rb +7 -0
  50. data/test/dummy/app/models/article.rb +1 -0
  51. data/test/dummy/app/models/comment.rb +7 -0
  52. data/test/dummy/app/services/article_service.rb +2 -0
  53. data/test/dummy/app/services/comment_service.rb +7 -0
  54. data/test/dummy/bin/rails +1 -1
  55. data/test/dummy/config/application.rb +2 -14
  56. data/test/dummy/config/locales/en.yml +9 -0
  57. data/test/dummy/config/routes.rb +6 -1
  58. data/test/dummy/db/migrate/20150717121532_create_articles.rb +1 -1
  59. data/test/dummy/db/migrate/20150907133753_create_admin_users.rb +1 -1
  60. data/test/dummy/db/migrate/20160713134238_create_comment.rb +9 -0
  61. data/test/dummy/db/migrate/20170207081043_create_another_admin_user.rb +10 -0
  62. data/test/dummy/db/schema.rb +26 -11
  63. data/test/fakes/article.rb +1 -1
  64. data/test/fakes/article_service.rb +3 -7
  65. data/test/generators/resource_generator_test.rb +77 -0
  66. data/test/integration/authentication_test.rb +8 -0
  67. data/test/integration/authorization_test.rb +5 -0
  68. data/test/integration/nested_resources_test.rb +47 -0
  69. data/test/test_helper.rb +1 -4
  70. data/test/{lib/godmin → unit}/engine_wrapper_test.rb +1 -1
  71. data/test/{lib/godmin → unit}/helpers/filters_test.rb +0 -0
  72. data/test/{lib/godmin → unit}/paginator_test.rb +11 -0
  73. data/test/{lib/godmin → unit}/resolver_test.rb +0 -0
  74. data/test/{lib/godmin → unit}/resources/resource_service/batch_actions_test.rb +1 -1
  75. data/test/{lib/godmin → unit}/resources/resource_service/filters_test.rb +1 -1
  76. data/test/{lib/godmin → unit}/resources/resource_service/ordering_test.rb +1 -1
  77. data/test/{lib/godmin → unit}/resources/resource_service/pagination_test.rb +0 -0
  78. data/test/{lib/godmin → unit}/resources/resource_service/scopes_test.rb +0 -0
  79. data/test/{lib/godmin → unit}/resources/resource_service_test.rb +0 -0
  80. metadata +167 -107
  81. data/gemfiles/rails_4.gemfile +0 -9
  82. data/lib/godmin/authorization/policy_finder.rb +0 -31
  83. data/lib/tasks/godmin_tasks.rake +0 -4
  84. 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.parents.find do |parent|
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(authentication install policy resource).map do |path|
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
- @namespace ||= Rails::Generators.namespace
15
+ @_namespace ||= Rails::Generators.namespace
16
16
  end
17
17
 
18
18
  def namespaced?
19
- @namespaced ||= namespace.present?
19
+ @_namespaced ||= namespace.present?
20
20
  end
21
21
 
22
22
  def namespaced_path
23
- @namespaced_path ||= begin
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 namespace
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
- @class_name ||= name.classify
19
+ @_class_name ||= name.classify
20
20
  end
21
21
 
22
22
  def class_path
23
- @class_path ||= namespaced_path + name.classify.deconstantize.split("::").map(&:underscore)
23
+ @_class_path ||= namespaced_path + name.classify.deconstantize.split("::").map(&:underscore)
24
24
  end
25
25
 
26
26
  def file_name
27
- @file_name ||= class_name.demodulize.underscore
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
- if @_partial_override[partial].nil?
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
- yield
17
+ capture(&block)
18
18
  end
19
19
  end
20
20
 
@@ -6,7 +6,7 @@ module Godmin
6
6
 
7
7
  link_to(
8
8
  translate_scoped("batch_actions.labels.#{name}", default: name.to_s.titleize),
9
- @resource_class,
9
+ [*@resource_parents, @resource_class],
10
10
  method: :patch,
11
11
  class: "btn btn-default hidden",
12
12
  data: {
@@ -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, { builder: FormBuilders::FormBuilder, inline_errors: false }.merge(options), &block)
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
@@ -1,12 +1,12 @@
1
1
  module Godmin
2
2
  class Paginator
3
- WINDOW_SIZE = 7.freeze
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 = resources
9
- @per_page = 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 ||= @resources.count
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
@@ -1,3 +1,6 @@
1
+ require "action_view"
2
+ require "action_view/template/resolver"
3
+
1
4
  module Godmin
2
5
  class Resolver < ::ActionView::FileSystemResolver
3
6
  def self.resolvers(controller_path, engine_wrapper)
@@ -13,15 +16,30 @@ module Godmin
13
16
  @engine_wrapper = engine_wrapper
14
17
  end
15
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.
16
36
  def find_templates(name, prefix, *args)
17
37
  templates = []
18
38
 
19
39
  template_paths(prefix).each do |path|
20
- if templates.present?
21
- break
22
- else
23
- templates = super(name, path, *args)
24
- end
40
+ break if templates.present?
41
+
42
+ templates = super(name, path, *args)
25
43
  end
26
44
 
27
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
- resource_service_class.new(admin_user: admin_user)
103
- else
104
- resource_service_class.new
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
@@ -33,7 +33,7 @@ module Godmin
33
33
  end
34
34
  end
35
35
 
36
- redirect_back
36
+ redirect_back(fallback_location: root_path)
37
37
  end
38
38
 
39
39
  def batch_action_ids
@@ -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
- @options[:resource_class] || resource_class_name.constantize
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
- resource_class.all
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
@@ -1,3 +1,3 @@
1
1
  module Godmin
2
- VERSION = "1.3.0"
2
+ VERSION = "2.1.0"
3
3
  end
data/template.rb CHANGED
@@ -1,10 +1,15 @@
1
1
  require "active_support/all"
2
2
 
3
3
  def install_standalone
4
- gem "godmin", "1.2.0"
4
+ set_ruby_version
5
+
6
+ gem "godmin", "1.5.0"
5
7
 
6
8
  after_bundle do
7
- generate_model
9
+ create_database
10
+
11
+ generate_models
12
+
8
13
  generate("godmin:install")
9
14
  generate("godmin:resource", "article")
10
15
  generate("godmin:resource", "author")
@@ -16,12 +21,15 @@ def install_standalone
16
21
  modify_author_service
17
22
  modify_article_controller
18
23
  modify_article_service
24
+ modify_readme
19
25
 
20
26
  migrate_and_seed
21
27
  end
22
28
  end
23
29
 
24
30
  def install_engine
31
+ set_ruby_version
32
+
25
33
  run_ruby_script("bin/rails plugin new admin --mountable")
26
34
 
27
35
  gsub_file "admin/admin.gemspec", "TODO: ", ""
@@ -29,14 +37,17 @@ def install_engine
29
37
 
30
38
  inject_into_file "admin/admin.gemspec", before: /^end/ do
31
39
  <<-END.strip_heredoc.indent(2)
32
- s.add_dependency "godmin", "~> 1.0.0"
40
+ s.add_dependency "godmin", "~> 1.5.0"
33
41
  END
34
42
  end
35
43
 
36
44
  gem "admin", path: "admin"
37
45
 
38
46
  after_bundle do
39
- generate_model
47
+ create_database
48
+
49
+ generate_models
50
+
40
51
  run_ruby_script("admin/bin/rails g godmin:install")
41
52
  run_ruby_script("admin/bin/rails g godmin:resource article")
42
53
  run_ruby_script("admin/bin/rails g godmin:resource author")
@@ -54,12 +65,24 @@ def install_engine
54
65
  modify_author_service("admin")
55
66
  modify_article_controller("admin")
56
67
  modify_article_service("admin")
68
+ modify_readme
57
69
 
58
70
  migrate_and_seed
59
71
  end
60
72
  end
61
73
 
62
- def generate_model
74
+ def set_ruby_version
75
+ prepend_to_file "Gemfile" do
76
+ "ruby '2.3.5'\n"
77
+ end
78
+ end
79
+
80
+ def create_database
81
+ rake("db:drop")
82
+ rake("db:create")
83
+ end
84
+
85
+ def generate_models
63
86
  generate(:model, "author name:string")
64
87
  generate(:model, "article title:string body:text author:references published:boolean published_at:datetime")
65
88
 
@@ -106,6 +129,7 @@ def modify_rakefile
106
129
  desc "Reseed the database"
107
130
  task reseed: :environment do
108
131
  Rake::Task["sandbox:reset"].invoke
132
+ Rake::Task["db:environment:set"].invoke
109
133
  Rake::Task["db:schema:load"].invoke
110
134
  Rake::Task["db:seed"].invoke
111
135
  end
@@ -285,9 +309,20 @@ def modify_author_service(namespace = nil)
285
309
  END
286
310
  end
287
311
  end
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
+
288
325
  def migrate_and_seed
289
- rake("db:drop")
290
- rake("db:create")
291
326
  rake("db:migrate")
292
327
  rake("db:seed")
293
328
  end