Skip to content

Instantly share code, notes, and snippets.

@graysonchen
Forked from DotHide/rails-api-template.rb
Created April 16, 2019 14:56
Show Gist options
  • Save graysonchen/f5af430367258e773d80c10542c10654 to your computer and use it in GitHub Desktop.
Save graysonchen/f5af430367258e773d80c10542c10654 to your computer and use it in GitHub Desktop.

Revisions

  1. @DotHide DotHide revised this gist Aug 9, 2016. 1 changed file with 266 additions and 20 deletions.
    286 changes: 266 additions & 20 deletions rails-api-template.rb
    Original file line number Diff line number Diff line change
    @@ -19,12 +19,17 @@ def render_file(text, variables)
    add_source 'https://rubygems.org/'

    gem 'puma', '~> 3.0'
    gem 'rails', '~> 5.0'
    gem 'slowpoke'
    gem 'mysql2', '>= 0.3.18', '< 0.5' # Use mysql as the database for Active Record
    gem 'rails', '~> 5.0.0'
    gem 'lograge'
    gem 'wisper'
    gem 'wisper', '2.0.0.rc1'
    gem 'active_model_serializers'
    gem 'rack-attack' # Rack middleware for blocking & throttling abusive requests
    gem 'rails-i18n', '~> 5.0.0'
    gem 'devise'
    gem 'devise-i18n'
    gem 'doorkeeper'
    gem 'doorkeeper-i18n'

    gem_group :development do
    gem 'thin'
    @@ -35,6 +40,7 @@ def render_file(text, variables)
    gem 'capistrano3-puma', require: false
    gem 'capistrano-sidekiq', require: false
    gem 'better_errors'
    gem 'listen', '~> 3.0.5'
    end

    gem_group :test do
    @@ -44,7 +50,8 @@ def render_file(text, variables)
    end

    gem_group :development, :test do
    gem 'spring'
    gem 'rubocop', require: false
    gem 'rspec-rails'
    gem 'pry-rails'
    gem 'pry-byebug'
    gem 'awesome_print'
    @@ -54,35 +61,49 @@ def render_file(text, variables)

    run 'bundle install'

    after_bundle do
    setup_application
    setup_database
    # set_routes
    # prepare_files
    # setup_i18n
    # setup_cable
    # setup_vendor
    # setup_git
    end

    # ====================
    # 2. application.rb
    # ====================

    generators_config = <<-EOS
    config.generators do |g|
    g.test_framework :rspec
    g.fixture_replacement :factory_girl, dir: 'spec/factories'
    end
    EOS
    def setup_application
    generators_config = <<-EOS
    config.generators do |g|
    g.test_framework :rspec
    g.fixture_replacement :factory_girl, dir: 'spec/factories'
    end
    EOS

    environment "config.time_zone = 'Beijing'"
    environment "config.i18n.available_locales = ['zh-CN', :en]"
    environment "config.i18n.default_locale = 'zh-CN'"
    environment 'config.i18n.fallbacks = true'
    environment 'config.middleware.use Rack::Attack'
    environment generators_config
    environment "config.time_zone = 'Beijing'"
    environment "config.i18n.available_locales = ['zh-CN', :en]"
    environment "config.i18n.default_locale = 'zh-CN'"
    environment 'config.i18n.fallbacks = true'
    environment 'config.middleware.use Rack::Attack'
    environment generators_config
    end

    # ====================
    # 3. database.yml
    # ====================

    database_temp = <<-EOS
    def setup_database
    database_temp = <<-EOS
    default: &default
    adapter: mysql2
    encoding: utf8
    pool: 5
    username: root
    password:
    password: <%= mysql_passwd %>
    host: localhost
    development:
    @@ -94,5 +115,230 @@ def render_file(text, variables)
    database: <%= app_name %>_test
    EOS

    run 'rm config/database.yml'
    file 'config/database.yml', render_file(database_temp, app_name: app_name.downcase)
    run 'rm config/database.yml'
    file 'config/database.yml', render_file(database_temp, app_name: app_name.downcase, mysql_passwd: ENV['LOCAL_MYSQL_PASSWD'])

    # drop_db = yes?('Drop DB for initialize? (Y/n)')
    # rails_command 'db:drop' if drop_db
    # rails_command 'db:setup' if drop_db
    # rails_command 'db:migrate'
    end

    # ====================
    # 4. routes.rb
    # ====================

    def set_routes
    api_temp = <<-EOS
    namespace :api do
    namespace :v1 do
    match 'public', via: :get, to: 'root#public'
    match '*path', via: :all, to: 'root#not_found'
    end
    end
    EOS

    route "root to: 'home#index'"
    route api_temp
    end

    # ====================
    # 5. Files Ready
    # ====================

    def prepare_files
    home_ctrl_temp = <<EOS
    class HomeController < ApplicationController
    def index
    end
    end
    EOS

    file 'app/controllers/home_controller.rb', home_ctrl_temp

    api_app_temp = <<EOS
    module Api
    module V1
    class ApplicationController < ActionController::API
    class ParameterValueNotAllowed < ActionController::ParameterMissing
    attr_reader :values
    def initialize(param, values) # :nodoc:
    @param = param
    @values = values
    super("param: \#{param} value only allowed in: \#{values}")
    end
    end
    class AccessDenied < StandardError; end
    class PageNotFound < StandardError; end
    rescue_from(ActionController::ParameterMissing) do |err|
    render json: { error: 'ParameterInvalid', message: err }, status: 400
    end
    rescue_from(ActiveRecord::RecordInvalid) do |err|
    render json: { error: 'RecordInvalid', message: err }, status: 400
    end
    rescue_from(AccessDenied) do |err|
    render json: { error: 'AccessDenied', message: err }, status: 403
    end
    rescue_from(ActiveRecord::RecordNotFound) do
    render json: { error: 'ResourceNotFound' }, status: 404
    end
    def requires!(name, opts = {})
    opts[:require] = true
    optional!(name, opts)
    end
    def optional!(name, opts = {})
    if params[name].blank? && opts[:require] == true
    raise ActionController::ParameterMissing.new(name)
    end
    if opts[:values] && params[name].present?
    values = opts[:values].to_a
    if !values.include?(params[name]) && !values.include?(params[name].to_i)
    raise ParameterValueNotAllowed.new(name, opts[:values])
    end
    end
    if params[name].blank? && opts[:default].present?
    params[name] = opts[:default]
    end
    end
    def error!(data, status_code = 400)
    render json: data, status: status_code
    end
    def error_404!
    error!({ 'error' => 'Page not found' }, 404)
    end
    end
    end
    end
    EOS

    api_root_temp = <<EOS
    module Api
    module V1
    class RootController < Api::V1::ApplicationController
    # Require access token for all actions
    # before_action :doorkeeper_authorize!
    def not_found
    raise ActiveRecord::RecordNotFound
    end
    def public
    { message: I18n.t('v1.root.public.success') }
    end
    end
    end
    end
    EOS

    file 'app/controllers/api/v1/application_controller.rb', api_app_temp
    file 'app/controllers/api/v1/root_controller.rb', api_root_temp
    end

    # ====================
    # 6. I18n
    # ====================

    def setup_i18n
    run 'rm config/locales/en.yml'
    rails_command 'g devise:i18n:views'

    i18n_api_en_temp = <<EOS
    en:
    v1:
    root:
    public:
    success: 'You're getting public API successfully.'
    EOS

    i18n_api_zhcn_temp = <<EOS
    zh-CN:
    v1:
    root:
    public:
    success: 'API 已可访问'
    EOS

    file 'config/locales/api.en.yml', i18n_api_en_temp
    file 'config/locales/api.zh-CN.yml', i18n_api_zhcn_temp
    end

    # ====================
    # 7. cable.yml
    # ====================

    def setup_cable
    cable_temp = <<-EOS
    production: &defaults
    adapter: redis
    url: redis://localhost:6379/1
    timeout: 1
    development:
    <<: *defaults
    url: redis://localhost:6379/2
    test:
    <<: *defaults
    url: redis://localhost:6379/3
    EOS

    run 'rm config/cable.yml'
    file 'config/cable.yml', cable_temp
    end

    # ====================
    # 8. Vendor Configs
    # ====================

    def setup_vendor
    # lograge
    lograge_temp = <<-EOS
    <%= app_name.gsub('-', '_').camelize %>::Application.configure do
    config.lograge.enabled = true
    end
    EOS
    initializer 'lograge.rb', render_file(lograge_temp, app_name: app_name)

    # Devise
    rails_command 'g devise:install'
    environment "config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }", env: 'development'
    rails_command 'g devise User'
    rails_command 'db:migrate'

    # Doorkeeper
    rails_command 'g doorkeeper:install'
    rails_command 'g doorkeeper:migration'
    rails_command 'db:migrate'
    end

    # ====================
    # 8. Git Config
    # ====================

    def setup_git
    file '.gitignore', <<-EOS
    .bundle
    tmp/
    db/*.sqlite3
    log/
    .sass-cache/
    config/*.yml
    .DS_Store
    *.swp
    *.swo
    .rvmrc
    .idea
    EOS

    git :init
    git add: '.'
    git commit: "-a -m 'Initial commit'"
    end
  2. @DotHide DotHide revised this gist Aug 4, 2016. 1 changed file with 62 additions and 7 deletions.
    69 changes: 62 additions & 7 deletions rails-api-template.rb
    Original file line number Diff line number Diff line change
    @@ -1,28 +1,38 @@
    # ==========
    require 'erb'
    require 'ostruct'

    # ====================
    # 0. Helper
    # ====================

    def render_file(text, variables)
    struct = OpenStruct.new(variables)
    rendered_file = ERB.new(text).result(struct.instance_eval { binding })
    end

    # ====================
    # 1. Gem File
    # ==========
    # ====================

    run 'rm Gemfile && touch Gemfile'

    add_source "https://rubygems.org/"

    append_file 'Gemfile', 'ruby 2.3.1'
    add_source 'https://rubygems.org/'

    gem 'puma', '~> 3.0'
    gem 'rails', '~> 5.0'
    gem 'slowpoke'
    gem 'lograge'
    gem 'wisper'
    gem 'active_model_serializers'
    gem 'high_voltage'
    gem 'rack-attack' # Rack middleware for blocking & throttling abusive requests

    gem_group :development do
    gem 'thin'
    gem 'capistrano', require: false
    gem 'capistrano-bundler', require: false
    gem 'capistrano-chruby', require: false
    gem 'capistrano-rails', require: false
    gem 'capistrano3-puma', github: "seuros/capistrano-puma"
    gem 'capistrano3-puma', require: false
    gem 'capistrano-sidekiq', require: false
    gem 'better_errors'
    end
    @@ -41,3 +51,48 @@
    gem 'faker'
    gem 'binding_of_caller'
    end

    run 'bundle install'

    # ====================
    # 2. application.rb
    # ====================

    generators_config = <<-EOS
    config.generators do |g|
    g.test_framework :rspec
    g.fixture_replacement :factory_girl, dir: 'spec/factories'
    end
    EOS

    environment "config.time_zone = 'Beijing'"
    environment "config.i18n.available_locales = ['zh-CN', :en]"
    environment "config.i18n.default_locale = 'zh-CN'"
    environment 'config.i18n.fallbacks = true'
    environment 'config.middleware.use Rack::Attack'
    environment generators_config

    # ====================
    # 3. database.yml
    # ====================

    database_temp = <<-EOS
    default: &default
    adapter: mysql2
    encoding: utf8
    pool: 5
    username: root
    password:
    host: localhost
    development:
    <<: *default
    database: <%= app_name %>_development
    test:
    <<: *default
    database: <%= app_name %>_test
    EOS

    run 'rm config/database.yml'
    file 'config/database.yml', render_file(database_temp, app_name: app_name.downcase)
  3. @DotHide DotHide renamed this gist Aug 4, 2016. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. @DotHide DotHide created this gist Aug 4, 2016.
    43 changes: 43 additions & 0 deletions .rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    # ==========
    # 1. Gem File
    # ==========

    run 'rm Gemfile && touch Gemfile'

    add_source "https://rubygems.org/"

    append_file 'Gemfile', 'ruby 2.3.1'

    gem 'puma', '~> 3.0'
    gem 'rails', '~> 5.0'
    gem 'slowpoke'
    gem 'lograge'
    gem 'wisper'
    gem 'active_model_serializers'
    gem 'high_voltage'

    gem_group :development do
    gem 'thin'
    gem 'capistrano', require: false
    gem 'capistrano-bundler', require: false
    gem 'capistrano-chruby', require: false
    gem 'capistrano-rails', require: false
    gem 'capistrano3-puma', github: "seuros/capistrano-puma"
    gem 'capistrano-sidekiq', require: false
    gem 'better_errors'
    end

    gem_group :test do
    gem 'rspec'
    gem 'factory_girl_rails'
    gem 'database_cleaner'
    end

    gem_group :development, :test do
    gem 'spring'
    gem 'pry-rails'
    gem 'pry-byebug'
    gem 'awesome_print'
    gem 'faker'
    gem 'binding_of_caller'
    end