Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add scaffold generators #794

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Add scaffold generators #794

wants to merge 1 commit into from

Conversation

hoverjet
Copy link

This PR introduces a Pundit generator for Rails scaffolds and adds authorize and policy_scope Pundit's methods to scaffolded controllers. It modifies the scaffold generator to include a hook for Pundit policies and overrides scaffold controller templates through a Railtie to add Pundit's methods.
Example scaffold command:

# rails g scaffold Post
      invoke  active_record
      create    db/migrate/20240225223237_create_posts.rb
      create    app/models/post.rb
      invoke    rspec
      create      spec/models/post_spec.rb
      invoke  resource_route
       route    resources :posts
      invoke  scaffold_controller
      create    app/controllers/posts_controller.rb
      invoke    erb
      create      app/views/posts
      create      app/views/posts/index.html.erb
      create      app/views/posts/edit.html.erb
      create      app/views/posts/show.html.erb
      create      app/views/posts/new.html.erb
      create      app/views/posts/_form.html.erb
      create      app/views/posts/_post.html.erb
      invoke    resource_route
      invoke    rspec
      create      spec/requests/posts_spec.rb
      create      spec/views/posts/edit.html.erb_spec.rb
      create      spec/views/posts/index.html.erb_spec.rb
      create      spec/views/posts/new.html.erb_spec.rb
      create      spec/views/posts/show.html.erb_spec.rb
      create      spec/routing/posts_routing_spec.rb
      invoke    helper
      create      app/helpers/posts_helper.rb
      invoke      rspec
      create        spec/helpers/posts_helper_spec.rb
      invoke    jbuilder
      create      app/views/posts/index.json.jbuilder
      create      app/views/posts/show.json.jbuilder
      create      app/views/posts/_post.json.jbuilder
      invoke  policy
      create    app/policies/post_policy.rb
      invoke    rspec
      create      spec/policies/post_policy_spec.rb

Generated PostsController:

class PostsController < ApplicationController
  before_action :set_post, only: %i[show edit update destroy]

  # GET /posts
  def index
    @posts = policy_scope(Post.all)
  end

  # GET /posts/1
  def show
    authorize @post
  end

  # GET /posts/new
  def new
    @post = Post.new
    authorize @post
  end

  # GET /posts/1/edit
  def edit
    authorize @post
  end

  # POST /posts
  def create
    @post = Post.new(post_params)
    authorize @post

    if @post.save
      redirect_to @post, notice: "Post was successfully created."
    else
      render :new, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /posts/1
  def update
    authorize @post
    if @post.update(post_params)
      redirect_to @post, notice: "Post was successfully updated.", status: :see_other
    else
      render :edit, status: :unprocessable_entity
    end
  end

  # DELETE /posts/1
  def destroy
    authorize @post
    @post.destroy!
    redirect_to posts_url, notice: "Post was successfully destroyed.", status: :see_other
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = Post.find(params[:id])
      authorize @post
    end

    # Only allow a list of trusted parameters through.
    def post_params
      params.fetch(:post, {})
    end
end

@Burgestrand
Copy link
Member

I believe this introduces a dependency on Rails? Pundit should not have Rails as a dependency.

@hoverjet
Copy link
Author

I hope that by adding the condition require "pundit/railtie" if defined?(Rails), it is ensured that the gem can be used in both Rails and non-Rails Ruby environments. This makes the inclusion of the Railtie and generators optional and dependent on the runtime context.

@Burgestrand
Copy link
Member

I hope that by adding the condition require "pundit/railtie" if defined?(Rails), it is ensured that the gem can be used in both Rails and non-Rails Ruby environments. This makes the inclusion of the Railtie and generators optional and dependent on the runtime context.

I believe you're correct, that seems like it's the recommended approach when viewing the documentation: https://api.rubyonrails.org/classes/Rails/Railtie.html

I'm for the spirit of more guidance in how to use Pundit, and making it more convenient.

However, I'm significantly more hesitant towards providing and maintaining controller generation templates. That's a lot of code to have an opinion on, when Pundit is mostly only concerned with a relatively small part of the generated code.

My gut feeling is that I'd like a more surgical approach. I'm not sure that's possible.

Regardless I feel I also need to run this PR by another maintainer friend before making a decision.

@Burgestrand
Copy link
Member

I also missed that this PR was born out of #735

It's worth mentioning that I still think that generating policies automatically on scaffold is a good idea. Pundit kind of own policies in that sense, and can have opinions on how to write those.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants