You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# lib/generators/rspec/policy/policy_generator.rb
module Rspec
module Generators
class PolicyGenerator < Rails::Generators::NamedBase
source_root File.expand_path('templates', __dir__)
def copy_policy_spec_file
template 'policy_spec.erb', File.join("spec/policies", class_path, "#{file_name}_policy_spec.rb")
end
end
end
end
The spec's template
# lib/generators/rspec/policy/templates/policy_spec.erb
require 'spec_helper'
describe <%= class_name %>Policy do
pending "add some examples to (or delete) #{__FILE__}"
end
Application config to hook up custom generators
# config/application.rb
module YourAppName
class Application < Rails::Application
# ...
config.generators do |g|
g.test_framework :rspec
require './lib/generators/rails/policy/hooks'
end
end
end
@annikoff Thanks for actually pointing toward the solution.
I forgot I made it work with some tweaks and the changed code is working with ruby 3.0.0 and rails 6
config/initializers/pundit_policy_generator.rb
# frozen_string_literal: true
require 'rails/generators'
# NOTE: This is the only approach that works without skipping any existing
# generators.
# Other approaches tried:
# - Added hook in an initializer by opening class
# - Missing `jbuilder`
# - Added whole files at the same generator locations
# - Missing `controller_test` and `system test`
# - The existing approach https://gist.github.com/annikoff/331f785aa7a207a7945b1eca6eff526b
# - Missing model
module Rails
module Generators
class ScaffoldControllerGenerator < NamedBase
# invoke with scaffolding controllers' generators
hook_for :policy, in: :pundit, default: true, type: :boolean
end
class ControllerGenerator < NamedBase
# invoke with the controllers' generator.
hook_for :policy, in: :pundit, default: true, type: :boolean
end
end
end
# frozen_string_literal: true
# NOTE: Please do not remove this.
#
# This is required in order to invoke custom generators with the following
# command:
# rails g controller [controller name]
#
# We have already tried different approaches mentioned in:
# config/initializers/pundit_policy_generator.rb
#
module Rails
module Generators
class ControllerGenerator < NamedBase # :nodoc:
end
end
end
# frozen_string_literal: true
# NOTE: Please do not remove this.
#
# This is required in order to invoke custom generators with the following
# command:
# rails g scaffold [resource name]
#
# We have already tried different approaches mentioned in:
# config/initializers/pundit_policy_generator.rb
#
module Rails
module Generators
class ScaffoldControllerGenerator < NamedBase # :nodoc:
end
end
end
Your solution only half worked for me. While it did not skip any scaffolding and did scaffold policies, it stopped picking my custom scaffold templates in lib/templates/rails/scaffold_controller/controller.rb.tt
I've come to a perfect solution heavily inspired by
I only need 1 initializer to get everything working:
# Inspired by:
# - https://gist.github.com/annikoff/331f785aa7a207a7945b1eca6eff526b
# - https://github.com/drapergem/draper/blob/master/lib/generators/controller_override.rb
# - https://github.com/drapergem/draper/blob/master/lib/draper/railtie.rb
require "rails/railtie"
require "rails/generators"
require "generators/pundit/policy/policy_generator"
module CustomPunditGenerator
module ControllerGenerator
extend ActiveSupport::Concern
included do
hook_for :policy, in: :pundit, default: true, type: :boolean do |generator|
invoke generator, [name.singularize]
end
end
end
module ScaffoldControllerGenerator
extend ActiveSupport::Concern
included do
hook_for :policy, in: :pundit, default: true, type: :boolean
end
end
module PolicyGenerator
extend ActiveSupport::Concern
included do
source_root File.expand_path("templates", __dir__)
def create_policy
template(
Rails.root.join("lib/templates/pundit/scaffold/policy.rb.tt"),
File.join("app/policies", class_path, "#{file_name}_policy.rb")
)
end
end
end
end
module ActiveModel
class Railtie < Rails::Railtie
generators do |app|
Rails::Generators.configure! app.config.generators
Rails::Generators::ControllerGenerator.include CustomPunditGenerator::ControllerGenerator
Rails::Generators::ScaffoldControllerGenerator.include CustomPunditGenerator::ScaffoldControllerGenerator
Pundit::Generators::PolicyGenerator.include CustomPunditGenerator::PolicyGenerator
end
end
end
Edit: Specs for policies are no longer generated. It seems as soon as we do
require "rails/railtie"
require "rails/generators"
module CustomPolicyGenerator
module ControllerGenerator
extend ActiveSupport::Concern
included do
hook_for :custom_policy, in: nil, default: true, type: :boolean do |generator|
invoke generator, [name.singularize]
end
end
end
module ScaffoldControllerGenerator
extend ActiveSupport::Concern
included do
hook_for :custom_policy, in: nil, default: true, type: :boolean
end
end
end
module ActiveModel
class Railtie < Rails::Railtie
generators do |app|
Rails::Generators.configure! app.config.generators
Rails::Generators::ControllerGenerator.include CustomPolicyGenerator::ControllerGenerator
Rails::Generators::ScaffoldControllerGenerator.include CustomPolicyGenerator::ScaffoldControllerGenerator
end
end
end
Rails.application.config.generators do |g|
g.policy false
g.custom_policy true
end
module Rails
class CustomPolicyGenerator < Rails::Generators::NamedBase
# source_root File.expand_path("templates", __dir__)
def create_policy
template "policy.rb", File.join("app/policies", class_path, "#{file_name}_policy.rb")
end
hook_for :test_framework
end
end
module Rspec
class CustomPolicyGenerator < Rails::Generators::NamedBase
# source_root File.expand_path("templates", __dir__)
def create_policy_spec
template "policy_spec.rb", File.join("spec/policies", class_path, "#{file_name}_policy_spec.rb")
end
end
end
Placed template files in
lib/templates/rails/custom_policy/policy.rb.tt
lib/templates/rspec/custom_policy/policy_spec.rb.tt
module ActiveModel
class Railtie < Rails::Railtie
generators do |app|
Rails::Generators.configure! app.config.generators
Rails::Generators::ControllerGenerator.include CustomPolicyGenerator::ControllerGenerator
Rails::Generators::ScaffoldControllerGenerator.include CustomPolicyGenerator::ScaffoldControllerGenerator
end
end
end
is the best way but outside of that, Rails::Generators::ScaffoldControllerGenerator is not defined and I am forced to use a require. If I use the requires:
Thanks yall. I wrote a blogpost to cover what ended up working for me. I did end up needing the requires, but I wasn't using custom templates so not sure if it breaks that like you mentioned.
@annikoff
There's an issue with this approach. I am currently using this to generate policy files.
This for some reason is not creating model. It is skipping the model generator.
Did you face the same issue and did you add any workaround for the same?