Rails: 对功能一致的Controller动态生成Action

使用class_evalstring转换成实例方法

# app/controller/concern/website_action.rb

module WebsiteAction
  extend ActiveSupport::Concern

  included do
    before_action :find_website, only: %i[edit update destroy]
  end

  class_methods do
    def define_actions_for(klass)
      class_eval <<-RUBY, __FILE__, __LINE__ + 1
        def index
          @websites = #{klass}.all
        end

        def new
          @website = #{klass}.new
        end

        def create
          @website = #{klass}.new(website_params)
          if @website.save
            redirect_to action: :index
          else
            render :new
          end
        end

        def edit
        end

        def update
          if @website.update(website_params)
            redirect_to action: :index
          else
            render :edit
          end
        end

        def destroy
          @website.destroy
          redirect_to action: :index
        end

        private

        def find_website
          @website = #{klass}.find(params[:id])
        end

        def website_params
          params.require(#{klass.to_s.underscore.to_sym}).permit(:name, :link)
        end
      RUBY
    end
  end
end

在Controller使用类宏的方式加载Actions

class FriendWebsitesController < ApplicationController
  include WebsiteAction

  define_actions_for(FriendWebsite)
end