Warning: This guide intended for Rails 6.1. (It may not be complete)
This is direction for Migration from c9.io to AWS Cloud9 or to simply setup AWS Cloud9 for Rails Development, after you follow the cloud9 migration directions and created a workspace, keeping in mind the Workspace settings Section below.
Be sure you are using the right version of rails. You may need to remove rails and rail-ties and install rails 6.1. Check online for how (search how to reinstall rails with a specific version)
To create a new app in AWS Cloud9,
the directions are basically the same,
but you need to use rails new
(see note below first) first
and move all code out of the new folder
and into the workspace (root) folder,
so you don't need to CD into your project.
Note: When using Rails new it useful to review the rails new -h
to see what flags you can use.
Since this guide uses postgres, you'll want to use:
rails new app_name --database postgresql
- Click Environment
- Add name + Description
- Click Next
- Select "No Ingress" EC2 instance
- Select 2 GB of RAM (or higher)
- Select Ubuntu Server
- Click Next
- Create Environment
When creating a Cloud9 Environment, use Ubuntu not Amazon Linux
- Strip Whitespace
- Soft tabs (2)
Bash Alises: https://gist.github.com/MyklClason/d71a39ace28b9ec9f0ad
Be sure to update the name and email for git.
# Add to bottom of .bashrc file
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# General git config, be sure to update the name + email
git config --global user.name "<user name>"
git config --global user.email <user email>
# Add custom/modified aliases below here
# Then add profile env vars and project specific aliases and alias overrides below here
export HOST_URL="" # Add host URL
export HOST_DOMAIN="" # Add host domain
Close and reopen any open terminals after the above is ran to use the aliases.
Seems 10GB is never enough, increase to 20GB by following the below.
https://docs.aws.amazon.com/cloud9/latest/user-guide/move-environment.html
First run
sudo apt-get update
sudo apt install postgresql postgresql-contrib libpq-dev
One Liner
sudo apt-get update; sudo apt install postgresql postgresql-contrib libpq-dev
(The above can cause odd issues with the Y/N if it isn't ran by itself)
Then
# ubuntu User setup
sudo service postgresql start
sudo sudo -u postgres psql
CREATE USER ubuntu SUPERUSER PASSWORD 'password'; # You may want to use something more secure
\q
sudo apt-get install redis-server
npm install --global yarn
huf
If bash aliases are setup, else see bash aliases gist for what the alias is currently mapped to, as it has changed in the past depending on heroku CLI version).
heroku login -i
heroku git:clone -a
Adjust the time and remote as needed. Note: This needs to be done whenever the database is updated as well.
heroku pg:backups:schedule DATABASE_URL --at '02:00 America/Los_Angeles' --remote heroku
Cloud9 now doesn't really play nice with RVM, so Chruby is better if RVM isn't already installed.
- Install Manager: https://github.com/postmodern/chruby
- Install Ruby: https://github.com/postmodern/ruby-install#readme
- Use code below to switch ruby version
if [ -n "$BASH_VERSION" ] || [ -n "$ZSH_VERSION" ]; then
source /usr/local/share/chruby/chruby.sh
chruby ruby
fi
First install the correct version of ruby. Remove the default version if a downgrade is needed.
Update RVM and reload:
rvm get head && rvm reload
Check currently installed rubies against required version. Keep only the required version (unless you have a specific long term need for multiple ruby versions)
rvm list
Remove versions via (unless good reason for it, best to only have a single ruby version installed and set as the default and current):
rvm remove <not required version>
To list installable versions of ruby
rvm list known
To install latest stable version and set as default, use this alias:
rvmlid
install and use default version
rvm use --default --install <required version>
Newer versions of Ubuntu do not include OpenSSL 1.1 which breaks things in older versions of Ruby. So we need to install an older version of SSL then install the ruby version. Tested with Ruby 2.7.7 and Rails 5.
Sources: https://docs.openiam.com/docs-4.2.1.3/appendix/2-openssl (Dependencies install only) https://deanpcmad.com/2022/installing-older-ruby-versions-on-ubuntu-22-04/ (Compile SSL 1.1.1g, other versions of ruby may need a different version)
# Tested with
ruby '2.7.7'
gem 'rails', '~> 5.2.4', '>= 5.2.4.3'
gem 'pg', '>= 0.18', '< 2.0'
wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz
tar zxvf openssl-1.1.1g.tar.gz
cd openssl-1.1.1g
./config --prefix=$HOME/.openssl/openssl-1.1.1g --openssldir=$HOME/.openssl/openssl-1.1.1g
make
make test
make install
rm -rf ~/.openssl/openssl-1.1.1g/certs
ln -s /etc/ssl/certs ~/.openssl/openssl-1.1.1g/certs
rvm install ruby-2.7.7 --with-openssl-dir=$HOME/.openssl/openssl-1.1.1g
ctw # Close terminal windows and get back to the rails folder
run rails -v
to check your current version of rails. If that isn't the version you want:
Remove the current railties (you may need to add -v '5.0.0'
at the end) or something if you need to uninstall a specific version.
gem uninstall railties
Install the correct railties, in this case, anything that is at least 6.1.X but less than Rails 7
gem install railties -v '~> 6.1'
Here is an example for an exact version:
gem install railties -v '6.1.4.1'
Once that installs, you should update the gemfile to use the version of rails installed by the railties
Update the gemfile to use the correct version (if needed)
gem rails, '~> 6.1'
Though you should replace the ~> 6.1.0
with the actual version it installs ie:
gem rails, '6.1.4.1'
Create a new rails app if needed Add Setup Rails if needed (if not migrating)
https://guides.rubyonrails.org/v6.1/getting_started.html
Use rails new -h
to get the options for setup.
For simple rails apps, one can use these options:
--database=postgresql
for postgres--skip-test
if you won't be following TDD or plan to use rspec instead of the built-in test lib.
After rails new
has finished running:
- Move everything from it (including hidden files) to the "environment" folder within Cloud9.
- Delete the empty app folder
- Add
/.c9
to the gitignore - Run
gic
to perform the initial git commit on the repo.
Just make use of git clone
. One the repo has been cloned,
make sure to move all the files (be sure you have turned on viewing of hidden files in cloud9)
Note: It is possible to git clone from a heroku app, but it is not ideal to rely on this as it will only contain the branch that was pushed to heroku (typically master). This is especially true since GitHub now offers private as well as public repos for free.
Setup bundler
gem install bundler
bundle install
https://dev.to/coorasse/rails-7-bootstrap-5-and-importmaps-without-nodejs-4g8
Convert into a generator
Be sure you have replaced the sqlite gem with the pg
gem (if you didn't specify postgres on app create).
Depending on your version of rails, you may need to use a specific version of the pg gem.
Research online for which version of the gem for which version of rails.
Then you can setup the Rails database
# Do the postgres setup for cloud9
rake db:create
rake db:migrate
rake db:seed # Optional, may not always be needed or desired. Use caution. For new rails apps, this is safe to run as it does nothing.
You can run them all at once using:
rake db:create db:migrate db:seed
If not already done so, this is a good time to do a yarn install
for existing web apps. Otherwise the things will have problems.
Add to config/application.rb
to disable certain scaffold generation functionality and force SSL.
Cloud9 already uses SSL and you'll want SSL reguardless of whether you use a custom domain name or not.
config.force_ssl = true # Force SSL
config.generators do |g|
g.stylesheets false
g.jbuilder = false
end
# Set host for each environment via config vars
config.action_mailer.default_url_options = { host: ENV["HOST_URL"] }
Solves FATAL: Listen error: unable to monitor directories for changes.
error if it comes up.
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
For new rails apps, it is likely enough to just add /.c9
at the bottom of the file.
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile '~/.gitignore_global'
# Ignore bundler config.
/.bundle
# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
# Ignore pidfiles, but keep the directory.
/tmp/pids/*
!/tmp/pids/
!/tmp/pids/.keep
# Ignore uploaded files in development
/storage/*
!/storage/.keep
/node_modules
/yarn-error.log
/public/assets
.byebug_history
# Ignore master key for decrypting credentials and more.
/config/master.key
/public/packs
/public/packs-test
/node_modules
/yarn-error.log
yarn-debug.log*
.yarn-integrity
/config/database.yml
.c9/
To simply things, we add a Procfile that will tell heroku to run migrations whenever new code is pushed. Sometimes this may need to be disabled, but it is helpful more often than not.
Add Procfile
to the root directory with just this:
release: rake db:migrate
Create app and push to heroku
heroku create <app_name>
gphm # Push changes
Setup heroku backup (database must exist first)
heroku pg:backups:schedule DATABASE_URL --at '02:00 America/Los_Angeles'
Add devise gem
Follow the setup instructions before continuing. Generate devise model
rails generate devise User first_name:string last_name:string role:string
Add application controller level before filters. Skip the before_action
for public facing pages.
before_action :authenticate_user!
Commit changes and push to heroku (if using a single heroku enviornment)
gac "Add devise" && gphm
Add bootstrap gem and follow instructions for stylesheet:
https://github.com/twbs/bootstrap-rubygem
Setup instructions based on: https://rubyyagi.com/how-to-use-bootstrap-and-jquery-in-rails-6-with-webpacker/#installing
Rails 7 Update:
- Use https://dev.to/coorasse/rails-7-bootstrap-5-and-importmaps-without-nodejs-4g8 instead if using importmap.
Add bootstrap to your Gemfile:
gem 'bootstrap', '~> 5.1.3'
Import Bootstrap styles in app/assets/stylesheets/application.css.scss
(will need to add .scss
)
// Custom bootstrap variables must be set or imported before bootstrap.
@import "bootstrap";
yarn add bootstrap jquery popper.js @popperjs/core
Setup the webpack environment, config/webpack/environment.js
:
const { environment } = require('@rails/webpacker')
const webpack = require("webpack");
// Add an additional plugin of your choosing : ProvidePlugin
environment.plugins.append(
"Provide",
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
Popper: ["popper.js", "default"] // for Bootstrap 4
})
);
module.exports = environment
Add to app/javascript/packs/application.js
import "bootstrap"
Then after the all the .start()
:
var jQuery = require('jquery')
// include jQuery in global and window scope (so you can access it globally)
// in your web browser, when you type $('.div'), it is actually refering to global.$('.div')
global.$ = global.jQuery = jQuery;
window.$ = window.jQuery = jQuery;
Sadly these are bootstrap 3, but they are convient enough to still be useful even if they need adjustments for bootstrap 5.
https://github.com/seyhunak/twitter-bootstrap-rails (Just add the gem don't run the install task)
Add the gem:
gem "twitter-bootstrap-rails"
Add `.old` to `app/views/layout/application.html.erb` to avoid overriding.
Run the following to generate a new bootstrap themed application layout.
rails g bootstrap:layout application
Remove the favicon_link_tag
entries as better to use a favicon generator anyway.
Copy anything needed from the original layout to the new layout, replacing old content as needed. (probably just all the ERB besides the "yield")
Move the Navigation to a partial and render it.
<%= render partial: "layouts/application/nav" %>
and replace it with the correct code form the correct bootstrap version documentation page for navbars.
https://getbootstrap.com/docs/5.1/components/navbar/
Sample nav partial:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<%= navbar_brand_link_to "Brand" %>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
</ul>
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
</ul>
<ul class="navbar-nav ml-auto mb-2 mb-lg-0">
<% if user_signed_in? %>
<%= navbar_link_to "Log out", destroy_user_session_path, method: :delete %>
<% else %>
<%= navbar_link_to "Log in", new_user_session_path %>
<% end %>
</ul>
</div>
</div>
</nav>
Generate pages controller home action
rails g controller pages home
Add root path to routes:
root "pages#home"
If a dedicated home page isn't needed just adjust so it redirects to a specific existing page. Can also add logic so certain users are redirected to specific pages (IE: Dashboard pages).
Mutations (maintained, but no new features expected) or ActiveInteractions works well
Mutations Gem (see below for alternative)
Add the gem:
gem 'mutations'
Add the mutation template (for copy/pasting) at app/mutations/mutation_template.rb
class MutationTemplate < Mutations::Command
required do
end
optional do
end
def execute
end
end
# In a controller action (for instance), you can run it:
def create
end
bundle add active_interaction
Folder Structure
app
interactions
domain
list
find
create
update
# Add logic for individual fields if needed.
destroy
Add to app/interactions
Templates:
class ApplicationInteraction < ActiveInteraction::Base
end
class TemplateInteraction < ApplicationInteraction
end
Rails require hosts to be explictly added, heroku seems to do this automagically, but for cloud9, you'll need to add it manually.
Seems better to add it under config/environments/development.rb
.
Verify the server runs locally at this point and UI layout looks suitable.
bundle add view_component haml-rails dry-effects
Setup gem according to the getting started.
Within config/application.rb
config.view_component.generate.preview = true
config.view_component.generate.preview_path = "spec/components/previews"
Improve the code organization for views. Lets have it setup like this. Auto-generated views will need to be moved into the appropriate folder.
views
controllers/ # Views used by controllers
mailers/ # Views used by Mailers
layouts/
Add to ApplicationController
append_view_path Rails.root.join("app", "views", "controllers")
Add to ApplicationMailer
append_view_path Rails.root.join("app", "views", "mailers")
rgvc application --inline
https://github.com/allmarkedup/lookbook https://github.com/palkan/view_component-contrib https://evilmartians.com/chronicles/viewcomponent-in-the-wild-supercharging-your-components
- See latest version setup instructions for
kaminari
andransack
For basic code quality and automated testing, we want to setup Rubocop, Rspec and Husky. Husky makes pre-commit hooks easy to verify things before they get commited. The pre-commit hook can be skipped if needed.
# Development/Test
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[mri mingw x64_mingw]
gem "simplecov"
gem "simplecov-html"
gem "simplecov-lcov"
gem "rubocop-rails"
gem "rubocop-rspec"
gem "factory_bot_rails" # https://github.com/thoughtbot/factory_bot
gem "rails-controller-testing"
gem "rspec-rails", "~> 6.0.0"
gem "faker-bot" # Allows for querying faker data
gem "i18n-tasks", "~> 1.0.12" # Better management of i18n, though doesn't play nice with ViewComponent
# Top Level Gems
gem "faker", "~> 3.0" # Useful for generating test/sample data, so kept at high level rather than dev/test
- Bootstrap Nav Helper
- Bootstrap Flash Helper
- Pretty Helper
- Devise Bootstrap Views
- Search/Sort/Filter/Paginate
- Select2 Scripts
- New Relic
https://gist.github.com/MyklClason/09c6f58b9e6d21340582cbd6fbd3b8b8
https://gist.github.com/MyklClason/625c53576d8d0d584c2d19ce772542bc