Skip to content

Commit

Permalink
Simplify generators
Browse files Browse the repository at this point in the history
This moves the install generator and scaffold generator under a superglue namespace.

With the install generator, now we have `rails g superglue:install`, making use of
rails generators also gives us the ability to add options to the install.

With the scaffold generator, now we have `rails g superglue:scaffold`. This replaces
the previous clunky scaffold that had to disable templates.
  • Loading branch information
jho406 committed Nov 27, 2024
1 parent 796fae2 commit c87f93a
Show file tree
Hide file tree
Showing 30 changed files with 185 additions and 172 deletions.

This file was deleted.

68 changes: 0 additions & 68 deletions superglue_rails/lib/generators/rails/templates/controller.rb.tt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require "rails/generators/named_base"
require "rails/generators/resource_helpers"

module Superglue
module Generators
class InstallGenerator < Rails::Generators::Base
source_root File.expand_path("../templates", __FILE__)

def create_files
say "Copying application.js file to #{app_js_path}"
copy_file "#{__dir__}/templates/js/application.js", "#{app_js_path}/application.js"

say "Copying page_to_page_mapping.js file to #{app_js_path}"
copy_file "#{__dir__}/templates/js/page_to_page_mapping.js", "#{app_js_path}/page_to_page_mapping.js"

say "Copying flash.js file to #{app_js_path}"
copy_file "#{__dir__}/templates/js/flash.js", "#{app_js_path}/slices/flash.js"

say "Copying pages.js file to #{app_js_path}"
copy_file "#{__dir__}/templates/js/pages.js", "#{app_js_path}/slices/pages.js"

say "Copying store.js file to #{app_js_path}"
copy_file "#{__dir__}/templates/js/store.js", "#{app_js_path}/store.js"

say "Copying application_visit.js file to #{app_js_path}"
copy_file "#{__dir__}/templates/js/application_visit.js", "#{app_js_path}/application_visit.js"

say "Copying Superglue initializer"
copy_file "#{__dir__}/templates/initializer.rb", "config/initializers/superglue.rb"

say "Copying application.json.props"
copy_file "#{__dir__}/templates/application.json.props", "app/views/layouts/application.json.props"

say "Adding required member methods to ApplicationRecord"
add_member_methods

say "Installing FormProps"
run "bundle add form_props"

say "Installing Superglue and friends"
run "yarn add history react react-dom @reduxjs/toolkit react-redux @thoughtbot/superglue --save"

say "Superglue is Installed! 🎉", :green
end

private

def add_member_methods
inject_into_file "app/models/application_record.rb", after: "class ApplicationRecord < ActiveRecord::Base\n" do
<<-RUBY
def self.member_at(index)
offset(index).limit(1).first
end
def self.member_by(attr, value)
find_by(Hash[attr, value])
end
RUBY
end
end

def app_js_path
"app/javascript/"
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

require "rails/generators/rails/resource/resource_generator"

module Superglue
module Generators
class ScaffoldGenerator < Rails::Generators::ResourceGenerator # :nodoc:
remove_hook_for :resource_controller
remove_class_option :actions

class_option :resource_route, type: :boolean

hook_for :scaffold_controller, required: true
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# frozen_string_literal: true

# This file was copied over from Rails land and slightly modified to account
# for Superglue templates

require "rails/generators/resource_helpers"
require "rails/generators/rails/scaffold_controller/scaffold_controller_generator"

module Superglue
module Generators
class ScaffoldControllerGenerator < Rails::Generators::NamedBase # :nodoc:
include Rails::Generators::ResourceHelpers

# Superglue uses the out-of-the-box controller generated by Rails.
source_root Rails::Generators::ScaffoldControllerGenerator.source_root

check_class_collision suffix: "Controller"

class_option :helper, type: :boolean
class_option :orm, banner: "NAME", type: :string, required: true,
desc: "ORM to generate the controller for"

class_option :skip_routes, type: :boolean, desc: "Don't add routes to config/routes.rb."

argument :attributes, type: :array, default: [], banner: "field:type field:type"

def create_controller_files
template "controller.rb", File.join("app/controllers", controller_class_path, "#{controller_file_name}_controller.rb")
end

# Replaces template_engine (and its default erb), with view_collection
# defaulting to superglue:view_collection
hook_for :view_collection, required: true, default: "view_collection"

hook_for :resource_route, in: :rails, required: true do |route|
invoke route unless options.skip_routes?
end

hook_for :test_framework, in: :rails, as: :scaffold

# Invoke the helper using the controller name (pluralized)
hook_for :helper, in: :rails, as: :scaffold do |invoked|
invoke invoked, [controller_name]
end

private

def permitted_params
attachments, others = attributes_names.partition { |name| attachments?(name) }
params = others.map { |name| ":#{name}" }
params += attachments.map { |name| "#{name}: []" }
params.join(", ")
end

def attachments?(name)
attribute = attributes.find { |attr| attr.name == name }
attribute&.attachments?
end
end
end
end
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
require "rails/generators/named_base"
require "rails/generators/resource_helpers"

module Rails
module Superglue
module Generators
class SuperglueGenerator < NamedBase
class ViewCollectionGenerator < Rails::Generators::NamedBase
include Rails::Generators::ResourceHelpers

source_root File.expand_path("../templates", __FILE__)
Expand All @@ -15,33 +15,56 @@ def create_root_folder
empty_directory path unless File.directory?(path)
end

def copy_view_files
%w[index show new edit].each do |view|
def copy_erb_files
available_views.each do |view|
@action_name = view
filename = filename_with_extensions(view)
template filename, File.join("app/views", controller_file_path, filename)
filename = filename_with_html_extensions(view)
template "erb/" + filename, File.join("app/views", controller_file_path, filename)
end
template "_form.json.props", File.join("app/views", controller_file_path, "_form.json.props")
end

%w[index show new edit].each do |view|
def copy_prop_files
available_views.each do |view|
@action_name = view
filename = filename_with_js_extensions(view)
template "web/" + filename, File.join("app/views", controller_file_path, filename)
filename = filename_with_extensions(view)
template "props/" + filename, File.join("app/views", controller_file_path, filename)
end

%w[index show new edit].each do |view|
template "props/_form.json.props", File.join("app/views", controller_file_path, "_form.json.props")
end

def copy_js_files
available_views.each do |view|
@action_name = view
filename = filename_with_html_extensions(view)
template "web/" + filename, File.join("app/views", controller_file_path, filename)
filename = filename_with_js_extensions(view)
template "js/" + filename, File.join("app/views", controller_file_path, filename)
end

%w[index show new edit].each do |view|
append_mapping(view)
template "props/_form.json.props", File.join("app/views", controller_file_path, "_form.json.props")
end

def append_mapping
available_views.each do |action|
app_js = "#{app_js_path}/page_to_page_mapping.js"

component_name = [plural_table_name, action].map(&:camelcase).join

prepend_to_file app_js do
"\nimport #{component_name} from '#{view_path}/#{controller_file_path}/#{action}'"
end

inject_into_file app_js, after: "pageIdentifierToPageComponent = {" do
"\n '#{[controller_file_path, action].join("/")}': #{component_name},"
end
end
end

protected

def available_views
%w(index edit show new)
end

def view_path
"../views"
end
Expand All @@ -50,20 +73,6 @@ def app_js_path
"app/javascript/"
end

def append_mapping(action)
app_js = "#{app_js_path}/page_to_page_mapping.js"

component_name = [plural_table_name, action].map(&:camelcase).join

prepend_to_file app_js do
"\nimport #{component_name} from '#{view_path}/#{controller_file_path}/#{action}'"
end

inject_into_file app_js, after: "pageIdentifierToPageComponent = {" do
"\n '#{[controller_file_path, action].join("/")}': #{component_name},"
end
end

attr_reader :action_name

def attributes_names
Expand Down Expand Up @@ -96,3 +105,4 @@ def attributes_list(attributes = attributes_names)
end
end
end

52 changes: 0 additions & 52 deletions superglue_rails/lib/install/web.rb

This file was deleted.

9 changes: 0 additions & 9 deletions superglue_rails/lib/tasks/install.rake

This file was deleted.

Loading

0 comments on commit c87f93a

Please sign in to comment.