Commit 0cb021d9 by ivan Lan

Update generator for controller & Add generator for migrations and views

parent 502e1edc
......@@ -3,37 +3,45 @@ require 'rails/generators/base'
module Shotengai
module Generators
class ControllersGenerator < Rails::Generators::Base
CONTROLLERS = %w(products ).freeze
desc <<-DESC.strip_heredoc
Create inherited Devise controllers in your app/controllers folder.
Use -n to add the namespec folder, default nil.
For example:
rails generate devise:controllers merchant -n=store
rails generate devise:controllers merchant -n store --product MyProduct --order MyOrder
This will create serveral controller classes inherited from merchant product and order class
For example:
app/controllers/store/product_controller.rb like this:
class Store::ProductsController < Shotengai::MerchantProductsController
class Store::MyProductsController < Shotengai::Merchant::ProductsController
content...
end
DESC
source_root File.expand_path("../../templates/controllers/", __FILE__)
source_root File.expand_path("../../templates/controllers", __FILE__)
argument :role, required: true,
desc: "The role to create controllers in merchant or customer"
class_option :namespace, aliases: "-n", type: :string,
desc: "Add namespace to controller"
class_option :product, type: :string, default: 'Product',
desc: "Product class name"
class_option :order, type: :string, default: 'Order',
desc: "Order class name"
def create_controllers
raise 'Illegal role. Only merchant or customer' unless role.in?(['merchant', 'customer'])
@namespace = options[:namespace].blank? ? '' : (options[:namespace].camelize + '::')
CONTROLLERS.each do |name|
template "#{role}/#{name}_controller.rb",
"app/controllers/#{options[:namespace]}/#{name}_controller.rb"
@controller_prefix = options[:namespace].blank? ? '' : (options[:namespace].camelize + '::')
{
'products' => options[:product],z
# orders: order,
# series: "#{Product}Series"
}.each do |key, klass_name|
@key, @klass_name = key, klass_name
template "#{role}/#{@key}_controller.rb",
"app/controllers/#{options[:namespace]}/#{klass_name.underscore.pluralize}_controller.rb"
end
end
end
......
require 'rails/generators/migration'
module Shotengai
module Generators
class MigrationsGenerator < Rails::Generators::Base
include Rails::Generators::Migration
desc 'Copy shotengai migrations to your application.'
def self.next_migration_number(dir)
Time.now.utc.strftime("%Y%m%d%H%M%S")
end
source_root File.expand_path("../../../../db/migrate", __FILE__)
def copy_migrations
# Use sort() to order the migrations by seq
# Use [2..-1] to delete the seq
Dir[ File.join(self.class.source_root, '*.rb') ].sort.each { |f|
copy_migration File.basename(f, '.rb')[2..-1]
}
end
protected
def copy_migration(filename)
if self.class.migration_exists?("db/migrate", "#{filename}")
say_status("skipped", "Migration #{filename} already exists")
else
migration_template "#{filename}.rb", "db/migrate/#{filename}.rb"
end
end
end
end
end
module Shotengai
module Generators
class ViewsGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/views", __FILE__)
desc "Copy shotengai views to your application."
# hide!
def copy_views
directory self.class.source_root, 'app/views/shotengai/'
end
end
end
end
class <%= @controller_prefix%><%= @klass_name.pluralize %>Controller < Shotengai::Customer::OrdersController
self.resource = '<%= @klass_name %>'
end
class <%= @controller_prefix%><%= @klass_name.pluralize %>Controller < Shotengai::Customer::ProductSeriesController
self.resource = '<%= @klass_name %>'
end
class <%= @namespace %>ProductController < Shotengai:Customer::ProductsController
# GET /resource/confirmation/new
# def new
# super
# end
class <%= @controller_prefix%><%= @klass_name.pluralize %>Controller < Shotengai:Customer::ProductsController
self.resource = '<%= @klass_name %>'
# POST /resource/confirmation
# def create
# super
# end
# GET /resource/confirmation?confirmation_token=abcdef
# def show
# super
# end
# protected
# The path used after resending confirmation instructions.
# def after_resending_confirmation_instructions_path_for(resource_name)
# super(resource_name)
# end
# The path used after confirmation.
# def after_confirmation_path_for(resource_name, resource)
# super(resource_name, resource)
# end
end
class <%= @controller_prefix%><%= @klass_name.pluralize %>Controller < Shotengai::Merchant::OrdersController
self.resource = '<%= @klass_name %>'
end
class <%= @controller_prefix%><%= @klass_name.pluralize %>Controller < Shotengai::Merchant::ProductSeriesController
self.resource = '<%= @klass_name %>'
end
class <%= @controller_prefix%><%= @klass_name.pluralize %>Controller < Shotengai::Customer::ProductsController
self.resource = '<%= @klass_name %>'
end
......@@ -13,4 +13,9 @@ module Shotengai
autoload :Catalog, 'shotengai/catalog'
autoload :AASM_DLC, 'shotengai/aasm_dlc'
autoload :WebError, 'shotengai/web_error'
autoload :Engine, 'shotengai/engine'
module Controller
end
end
module Shotengai
module ControllerHelper
module Product
included do
cattr_accessor :resource { 'Product' } # 默认值
# respond_with @products, template: "#{self.template_dir}/index"
cattr_accessor :template_dir { 'products/' }
end
class_methods do
def resource= resource_name
klass = Object.const_get resource_name
raise ArgumentError.new(
'The resource of Product Controller should be a class inherited from Shotengai::Product'
) unless Shotengai::Product === klass
@@resource = klass
end
# def template_dir dir
# self.template_dir = dir
# end
end
before_action :set_product, expect: [:index, :create]
respond_to :json
def index
@products = self.resource.all
respond_with @products, template: "#{self.template_dir}/index"
end
def show
@product = self.resource.find(params[:id])
respond_with @product, template: "#{self.template_dir}/show"
# need series list here
end
def create
self.resource.create!(product_params)
head 201
end
def update
self.resource.update!(product_params)
head 200
end
resource.aasm.state_machine.events.map(&:first).each do |event|
define_method(event) do
@product.send("#{event}!")
head 200
end
end
private
def set_resource
@product = self.resource.find(params[:id])
end
def product_params
resource_key = self.resource.model_name.singular.to_sym
# QUESTION: need these ?
spec = params.require(resource_key).fetch(:spec, nil).try(:permit!)
datail = params.require(resource_key).fetch(:datail, nil).try(:permit!)
meta = params.require(resource_key).fetch(:meta, nil).try(:permit!)
params.requrie().permit(
:title, :default_series_id,
:need_express, :need_time_attr, :cover_image,
banners: []
).merge(
{ spec: spec, detail: detail, meta: meta }
)
end
end
end
end
\ No newline at end of file
module Shotengai
module ControllerHelper
module Product
included do
# cattr_accessor :resource
end
class_methods do
def product_as resource_name
self.cattr_accessor :resource
self.resource = Object.const_get resource_name
end
end
before_action :set_product, expect: [:index, :create]
respond_to :json
def index
@products = self.resource.all
respond_with @products
end
def show
@product = self.resource.find(params[:id])
respond_with @product
end
def create
self.resource.create!(product_params)
head 201
end
def update
self.resource.update!(product_params)
head 200
end
resource.aasm.state_machine.events.map(&:first).each do |event|
define_method(event) do
@product.send("#{event}!")
head 200
end
end
private
def set_resource
@product = self.resource.find()
end
def product_params
resource_key = self.resource.model_name.singular.to_sym
# QUESTION: need these ?
spec = params.require(resource_key).fetch(:spec, nil).try(:permit!)
datail = params.require(resource_key).fetch(:datail, nil).try(:permit!)
meta = params.require(resource_key).fetch(:meta, nil).try(:permit!)
params.requrie().permit(
:title, :default_series_id,
:need_express, :need_time_attr, :cover_image,
banners: []
).merge(
{ spec: spec, detail: detail, meta: meta }
)
end
end
end
end
\ No newline at end of file
module Shotengai
module Controller
class ProductsMasterController
cattr_accessor :resource { 'Product' } # 默认值
# respond_with @products, template: "#{self.template_dir}/index"
cattr_accessor :template_dir { 'products/' }
class << self
def resource= resource_name
klass = Object.const_get resource_name
raise ArgumentError.new(
'The resource of Product Controller should be a class inherited from Shotengai::Product'
) unless Shotengai::Product === klass
@@resource = klass
end
end
before_action :set_product, expect: [:index, :create]
respond_to :json
def index
@products = self.resource.all
respond_with @products, template: "#{self.template_dir}/index"
end
def show
@product = self.resource.find(params[:id])
respond_with @product, template: "#{self.template_dir}/show"
# need series list here
end
def create
self.resource.create!(product_params)
head 201
end
def update
self.resource.update!(product_params)
head 200
end
resource.aasm.state_machine.events.map(&:first).each do |event|
define_method(event) do
@product.send("#{event}!")
head 200
end
end
private
def set_resource
@product = self.resource.find(params[:id])
end
def product_params
resource_key = self.resource.model_name.singular.to_sym
# QUESTION: need these ?
spec = params.require(resource_key).fetch(:spec, nil).try(:permit!)
datail = params.require(resource_key).fetch(:datail, nil).try(:permit!)
meta = params.require(resource_key).fetch(:meta, nil).try(:permit!)
params.requrie().permit(
:title, :default_series_id,
:need_express, :need_time_attr, :cover_image,
banners: []
).merge(
{ spec: spec, detail: detail, meta: meta }
)
end
end
end
end
end
module Shotengai
require 'rails/engine'
class Engine < ::Rails::Engine
end
end
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment