Coder Social home page Coder Social logo

fzingg / hyperloop-showcase-heroku Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 0.0 563 KB

Deployment of the Hyperloop-showcase on a HEROKU Server.

Ruby 1.87% JavaScript 97.31% CoffeeScript 0.03% CSS 0.11% HTML 0.69%
heroku tutorial rails hyperloop hyper-rails react-component isomorphic

hyperloop-showcase-heroku's Introduction

Deploying the Hyperloop Showcase App on Heroku (Debug way)

Preamble

This tutorial is the third in a series of four:

For more information: HyperLoop Web site

INTRODUCTION

This tutorial is a very detailed list of commands and file modifications to achieve a working deployment of the Hyperloop showcase on a Heroku Server.

Of course the Heroku deployment could be faster, but this tutorial allows programmers to check step by step where an error could happen.

The live Heroku demo deployment is here : https://damp-harbor-10403.herokuapp.com

The Hyperloop showcase has already been deployed successfully on a classic independent VPS (Rails 5.01, Capistrano and Passenger) : http://http://hyperloop-showcase.pixagency.com

DEPLOYING TUTORIAL

Set up a new Heroku app

heroku login
git clone https://github.com/heroku/ruby-getting-started.git
cd ruby-getting-started
heroku create
git push heroku master
heroku open

The initial Heroku app is coming with a Rails 4.x version. We are going to upgrade it to a Rails 5.0.1 version.

Upgrade to Rails 5.0.1

#Gemfile

		source 'https://rubygems.org'
		ruby '2.3.1'

		gem 'rails', '~> 5.0.1'
		gem 'puma', '3.7.0'
		gem "puma_worker_killer"
		gem 'sass-rails', '~> 5.0'
		gem 'uglifier', '>= 1.3.0'
		gem 'coffee-rails', '~> 4.2'
		gem 'pg', '0.18.4'
		gem 'jquery-rails'
		gem 'turbolinks', '~> 5'
		gem 'jbuilder', '~> 2.5'
		gem 'react-rails', '1.4.2'
		gem 'hyper-rails', '0.4.1'
		gem 'opal-rails', '0.9.1'
		gem 'opal-browser', '0.2.0'
		gem 'hyper-react', '0.11.0'
		gem 'hyper-router', '2.4.0'
		gem 'therubyracer', platforms: :ruby
		gem 'opal_hot_reloader', git: 'https://github.com/fkchang/opal-hot-reloader.git'
		gem 'foreman'

		group :development, :test do
		  gem 'byebug', platform: :mri
		end

		group :development do
		  gem 'web-console', '>= 3.3.0'
		  gem 'listen', '~> 3.0.5'
		  gem 'spring'
		  gem 'spring-watcher-listen', '~> 2.0.0'
		end

		gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
#config/environments/development.rb

		Rails.application.configure do
			    
			  config.cache_classes = false
			  config.eager_load = false 
			  config.consider_all_requests_local = true

			  if Rails.root.join('tmp/caching-dev.txt').exist?
			    config.action_controller.perform_caching = true

			    config.cache_store = :memory_store
			    config.public_file_server.headers = {
			      'Cache-Control' => 'public, max-age=172800'
			    }
			  else
			    config.action_controller.perform_caching = false

			    config.cache_store = :null_store
			  end
 
			  config.action_mailer.raise_delivery_errors = false
			  config.action_mailer.perform_caching = false
			  config.active_support.deprecation = :log
			  config.active_record.migration_error = :page_load		  
			  config.assets.debug = true
			  config.assets.quiet = true
			  config.file_watcher = ActiveSupport::EventedFileUpdateChecker
		end
#config/environments/production.rb

		Rails.application.configure do
			  
			  config.cache_classes = true  
			  config.eager_load = true
			  config.consider_all_requests_local       = false
			  config.action_controller.perform_caching = true 
			  config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?	 
			  config.assets.js_compressor = :uglifier			  
			  config.assets.compile = true			 
			  config.log_level = :debug			  
			  config.log_tags = [ :request_id ]			  
			  config.action_mailer.perform_caching = false		  
			  config.i18n.fallbacks = true		 
			  config.active_support.deprecation = :notify		 
			  config.log_formatter = ::Logger::Formatter.new		  

			  if ENV["RAILS_LOG_TO_STDOUT"].present?
			    logger           = ActiveSupport::Logger.new(STDOUT)
			    logger.formatter = config.log_formatter
			    config.logger = ActiveSupport::TaggedLogging.new(logger)
			  end
 
			  config.active_record.dump_schema_after_migration = false
		end
rm Gemfile.lock
bundle install
heroku local web

Browse to http://localhost:5000

Update database config file

#config/database.yml

	development:
	  <<: *default
	  database: ruby-getting-started_development
	  username: your-username
	  password: your-password
bundle exec rake db:create db:migrate
heroku local web

Browse to http://localhost:5000

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

Implement a React Component

//app/assets/javascripts/application.js

		//= require 'components'
		//= require 'react_ujs'
		//= require 'jquery'
		//= require 'jquery_ujs'

		//= require 'turbolinks'
		//= require_tree .

		Opal.load('components');
#app/views/components.rb

		require 'opal'
		require 'hyper-react'
		require 'react/react-source'
		require 'reactrb/auto-import'
		if React::IsomorphicHelpers.on_opal_client?
		  require 'opal-jquery'
		  require 'browser'
		  require 'browser/interval'
		  require 'browser/delay'
		  # add any additional requires that can ONLY run on client here
		end

		require_tree './components'
rails g hyperloop:component Home::Show
#config/routes.rb

		root 'home#show'
#app/controllers/home_controller.rb

		class HomeController < ApplicationController
		    def show
		    end
		end
#app/views/home/show.html.erb

<%= react_component 'Home::Show', {}, { prerender: false } %>
heroku local web

Browse to http://localhost:5000

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

HyperMesh Setup

#Gemfile

	gem 'hyper-mesh', '0.5.3'
bundle update
#app/views/components.rb

	require 'opal'

	require 'reactrb/auto-import'
	require 'react/react-source'
	require 'hyper-react'
	if React::IsomorphicHelpers.on_opal_client?
	  require 'opal-jquery'
	  require 'browser'
	  require 'browser/interval'
	  require 'browser/delay'
	  # add any additional requires that can ONLY run on client here
	end

	require 'hyper-mesh'
	require 'models'

	require_tree './components'
#config/application.rb
	...
	  class Application < Rails::Application
	    # Settings in config/environments/* take precedence over those specified here.
	    # Application configuration should go into files in config/initializers
	    # -- all .rb files in that directory are automatically loaded.
	    config.eager_load_paths += %W(#{config.root}/app/models/public)
	    config.autoload_paths += %W(#{config.root}/app/models/public)
	    config.assets.paths << ::Rails.root.join('app', 'models').to_s
	  end
	...
#routes.rb

mount HyperMesh::Engine => '/rr'
root 'home#show'
#app/models/models.rb

require_tree './public' if RUBY_ENGINE == 'opal'
#app/models/public/application_record.rb

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end
#app/policies/application_policy.rb

    # Policies regulate access to your public models
    # The following policy will open up full access (but only in development)
    # The policy system is very flexible and powerful.  See the documentation
    # for complete details.
    class ApplicationPolicy
      # Allow any session to connect:
      always_allow_connection
      # Send all attributes from all public models
      regulate_all_broadcasts { |policy| policy.send_all }
      # Allow all changes to public models
      allow_change(to: :all, on: [:create, :update, :destroy]) { true }
    end 
heroku local web

Browse to http://localhost:5000

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

Webpack Setup

npm init
npm install webpack --save-dev
npm install webpack -g
#/.gitignore

/node_modules
// webpack.config.js

var path = require("path");

module.exports = {
    context: __dirname,
    entry: {
      client_only:  "./webpack/client_only.js",
      client_and_server: "./webpack/client_and_server.js"
    },
    output: {
      path: path.join(__dirname, 'app', 'assets',   'javascripts', 'webpack'),
      filename: "[name].js",
      publicPath: "/webpack/"
    },
    module: {
      loaders: [
        // add any loaders here
      ]
    },
    resolve: {
    modules: [
    path.join(__dirname, "src"),
    "node_modules"
    ]
    },
};
// webpack/client_only.js

// any packages that depend specifically on the DOM go here
// for example the Webpack CSS loader generates code that will break prerendering
console.log('client_only.js loaded');
// webpack/client_and_server.js

// all other packages that you can run on both server (prerendering) and client go here
// most well behaved packages can be required here
console.log('client_and_server.js loaded');
webpack
// app/assets/javascripts/application.js

//= require 'components'
//= require 'react_ujs'
//= require 'jquery'
//= require 'jquery_ujs'
//= require 'webpack/client_only'
//= require 'turbolinks'
//= require_tree .

Opal.load('components');
#app/views/components.rb

require 'opal'

require 'hyper-react'
require 'webpack/client_and_server.js'
require 'reactrb/auto-import'
if React::IsomorphicHelpers.on_opal_client?
  require 'opal-jquery'
  require 'browser'
  require 'browser/interval'
  require 'browser/delay'
  # add any additional requires that can ONLY run on client here
end

require 'hyper-mesh'
require 'models'

require_tree './components'
npm install react --save 
npm install react-dom --save

// webpack/client_and_server.js

ReactDOM = require('react-dom')
React = require('react')
console.log('client_and_server.js loaded');
webpack
heroku local web

Browse to http://localhost:5000

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

ReactPlayer Component Config

npm install react-player --save
//webpack/client_and_server.js

ReactDOM = require('react-dom')
React = require('react')
console.log('client_and_server.js loaded');
ReactPlayer = require('react-player')
webpack
#app/views/components/home/show.rb

def render
  div do
    ReactPlayer(url:  'https://www.youtube.com/embed/FzCsDVfPQqk',
      playing: true
    )
  end
end
heroku local web

Browse to http://localhost:5000

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

React Bootstrap config

npm install bootstrap react-bootstrap --save
//webpack/client_and_server.js

ReactDOM = require('react-dom')
React = require('react')
console.log('client_and_server.js loaded');
ReactPlayer = require('react-player')
ReactBootstrap = require('react-bootstrap')
webpack
#app/views/components/home/show.rb

  def render
    ReactBootstrap::Button(bsStyle: 'success', bsSize: "small") do
      'Success'
    end.on(:click) do
      alert('you clicked me!')
    end
  end
heroku local web

Browse to http://localhost:5000

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

React BootstrapCSS setup

npm install css-loader file-loader style-loader url-loader --save-dev
// webpack.config.js

var path = require("path");

module.exports = {
    context: __dirname,
    entry: {
      client_only:  "./webpack/client_only.js",
      client_and_server: "./webpack/client_and_server.js"
    },
    output: {
      path: path.join(__dirname, 'app', 'assets',   'javascripts', 'webpack'),
      filename: "[name].js",
      publicPath: "/webpack/"
    },
    module: {
      rules: [
      { test: /\.css$/,
        use: [
          {
            loader: "style-loader"
          },
          {
            loader: "css-loader"
          }
        ]
      },
      { test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
        loader: 'url-loader?limit=10000&mimetype=application/font-woff'
      },
      { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
        loader: 'url-loader?limit=10000&mimetype=application/octet-stream'
      },
      { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
        loader: 'file-loader'
      },
      { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
      }
    ]
    },
    resolve: {
	modules: [
	path.join(__dirname, "src"),
	"node_modules"
	]
	},
};
//webpack/client_only.js

require('bootstrap/dist/css/bootstrap.css');
npm install bootstrap --save
webpack
#app/views/components/home/show.rb

module Components
  module Home
    class Show < React::Component::Base

      def say_hello(i)
        alert "Hello from number #{i}"
      end

      def render
        div do
          ReactBootstrap::Navbar(bsStyle: :inverse) do
            ReactBootstrap::Nav() do
              ReactBootstrap::NavbarBrand() do
                a(href: '#') { 'Hyperloop Showcase' }
              end
              ReactBootstrap::NavDropdown(
                eventKey: 1,
                title: 'Things',
                id: :drop_down
              ) do
                (1..5).each do |n|
                  ReactBootstrap::MenuItem(href: '#',
                    key: n,
                    eventKey: "1.#{n}"
                  ) do
                    "Number #{n}"
                  end.on(:click) { say_hello(n) }
                end
              end
            end
          end
          
        end
      end
    end
  end
end
heroku local web

Browse to http://localhost:5000

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

Bootswatch setup

npm install bootswatch
// webpack/client_only.js

// any packages that depend specifically on the DOM go here
// for example the Webpack CSS loader generates code that will break prerendering
console.log('client_only.js loaded');
require('bootstrap/dist/css/bootstrap.css');
require('bootswatch/superhero/bootstrap.min.css');
webpack
heroku local web

Browse http://localhost:5000

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

HyperMesh ActiveRecord model

rails g model Planevent
# db/migrate/..create_planevents.rb

class CreatePlanevents < ActiveRecord::Migration[5.0]
  def change
    create_table :planevents do |t|
      t.string :planeventtitle
      t.text :description
      t.timestamps
    end
  end
end
rails db:migrate
mv app/models/planevent.rb app/models/public
mv app/models/application_record.rb app/models/public
heroku run rake --trace db:migrate
# views/components/home/show.rb

module Components
  module Home
    class Show < React::Component::Base

      def say_hello(i)
        alert "Hello from number #{i}"
      end

      def render
        div do
          ReactBootstrap::Navbar(bsStyle: :inverse) do
            ReactBootstrap::Nav() do
              ReactBootstrap::NavbarBrand() do
                a(href: '') { 'HyperLoop Showcase' }
              end
              ReactBootstrap::NavDropdown(
                eventKey: 1,
                title: 'Things',
                id: :drop_down
              ) do
                (1..5).each do |n|
                  ReactBootstrap::MenuItem(href: '#',
                    key: n,
                    eventKey: "1.#{n}"
                  ) do
                    "Number #{n}"
                  end.on(:click) { say_hello(n) }
                end
              end
            end
          end
          div.container do
            
            PlaneventsList()
          end
        end
      end
    end
  end
end
#app/views/components/home/planeventslist.rb

module Components
  module Home
    class PlaneventsList < React::Component::Base

      define_state new_planevent: Hash.new { |h, k| h[k] = '' }

      before_mount do
        # note that this will lazy load posts
        # and only the fields that are needed will be requested
        @planevents = Planevent.all
        @planevent_attributes = Hash[ 'planeventtitle' => 'Event Name', 'description' => 'Description']
      end

      def render
        div.container do
            div.row do
                new_planevent
            end

            hr

            div.row do
                table_render
            end

        end
      end

      def table_render

          div.col_md_12 do
            br
            table(class: "table table-hover") do
              thead do
                tr do
                  td.text_muted.small(width: '33%') { "NAME" }
                  td.text_muted.small(width: '33%') { "DESCRIPTION" }
                  td.text_muted.small(width: '33%') { "DATE" }
                end
              end
              tbody do
                @planevents.reverse.each do |planevent|
                  PlaneventsListItem(planevent: planevent)
                end
              end
            end
          end

      end

      def new_planevent

        @planevent_attributes.each do |attribute, value|

            ReactBootstrap::FormGroup() do

                ReactBootstrap::ControlLabel() do
                    value
                end
                ReactBootstrap::FormControl(
                    value: state.new_planevent[attribute],
                    type: :text,
                    ).on(:change) { |e|
                        state.new_planevent![attribute] = e.target.value
                    }
            end
         end

        ReactBootstrap::Button(bsStyle: :primary) do
          "Create an new event"
        end.on(:click) { save_new_planevent }

      end

      def save_new_planevent

        Planevent.create(state.new_planevent) do |result|
          # note that save is a promise so this code will only run after the save
          # yet react will move onto the code after this (before the save happens)
          alert "unable to save" unless result == true
        end
        state.new_planevent.clear

      end
    end

    class PlaneventsListItem < React::Component::Base
      param :planevent

      def render

        tr do
          td(width: '33%') { params.planevent.planeventtitle }
          td(width: '33%') { params.planevent.description }
          td(width: '33%') { params.planevent.created_at.to_s }
        end

      end

    end
  end
end
heroku local web

Browse to http://localhost:5000

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

HyperMesh push notifications config

#config/initializers/hyper_mesh.rb

HyperMesh.configuration do |config|
  config.transport = :simple_poller
end
heroku local web

Browse to http://localhost:5000 with 2 different browsers and add a new Event. Both browsers should update the view with this new Event.

Push and test Heroku server

git add .
git commit -m "Demo"
git push heroku master
heroku open

hyperloop-showcase-heroku's People

Contributors

friism avatar fzingg avatar jonmountjoy avatar nicolasleger avatar ntassone avatar o-i avatar pmq20 avatar schneems avatar stevensonmt avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.