- https://guides.rubyonrails.org
- https://www.theodinproject.com/courses/ruby-on-rails
- https://thoughtbot.com/upcase/rails
gem install rails
- create the bitbucket repo
rails new PROJECTNAME -d postgresql
- do the bare rails new project push to the repo
- see: https://github.com/rspec/rspec-rails
- delete
test
folder, use only the spec from now on - see: https://github.com/thoughtbot/factory_bot_rails
- create the
spec/factories
folder - copy bin/rspec and then run
bundle binstubs bundler --force
- optional: https://github.com/travisjeffery/timecop
- use
gem "kaminari"
- use
gem "bootstrap_form", ">= 4.0.0.alpha1"
rails g kaminari:views bootstrap4
- create the
current_page
method at the admin controller - Partial
layouts/_form_record_errors
- example commit: https://bitbucket.org/RudineyFranceschi/cartax/commits/6a4fe418db05ed8cfb1d7f1867e233eb3c789cd0
- Amazon AWS Console (login with: infra.devmaker@gmail.com)
- Create a bucket and copy the configs from other bucket
- set the current CORS polycy
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>PUT</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration>
- create a new IAM user for the project
- set permission on this project buckets only (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_rw-bucket.html)
- Copy ID + Secret and Add them to s3 key at
rails credentials:edit
- add the
gem "aws-sdk-s3", "~> 1"
- copy the
aws.rb
initializer and update the settings
- Create a temporary Admin::Dashboard#index page
rails g controller Admir/Dashboard index
- Add devise: https://github.com/plataformatec/devise#getting-started
- follow after install instructions
root "admin/dashboard#index"
- dont need to generate the views yet
- add devise pt-BR translations with the gem: https://github.com/tigrish/devise-i18n
- Generate de user devise model:
rails generate devise User
- create the admin model with a polymorphic has_one relation to user
- add the polymorphic association
- Protect the admin Controller:
- Create the AdminController
- change the Admin::DashboardController
- https://bitbucket.org/RudineyFranceschi/cartax/commits/1ad21d0d356d6c975f6fd64c602b7f3d6325ef90
- add
gem "bootstrap_form", ">= 4.0.0.alpha1"
- add
gem "jquery-rails"
- copy de
package.json
file and runyarn install
- copy the entire
vendor/assets
folder - copy the
layout/application.html.erb
- copy
layouts/_flash_messages
- copy/edit
layouts/admin/header
- copy/edit
layouts/admin/menu
- change the
app/assets/images/logo
- copy
- create the
layout/admin.html.erb
- in
assets.rb
- add
admin.css admin.js
to precompiled_assets - add
Rails.application.config.assets.paths << Rails.root.join("vendor", "assets")
- add
- copy the
app/assets/stylesheets/admin.css
&app/assets/javascripts/admin.js
- copy the
admin/menu.js
- example commit: https://bitbucket.org/RudineyFranceschi/cartax/commits/8bb477a00c947eecb04b1b69573076e74e295997/
- see http://graphql-ruby.org/getting_started
- add
gem "graphql"
bin/rails generate graphql:install --schema=PublicSchema
⚠️ graphiql-rails has a bug. use version < 1.5 (see: rmosolgo/graphiql-rails#58)- Move & Rename genetared
MutationType
&QueryType
toPublicMutationType
&PublicQueryType
at the schema also - copy the
GraphqlControllerMixin
controller concern - move & change the
GraphqlController
toPublic/GraphqlController
- change the route to use the public/grapql controller
post "/graphql", to: "public/graphql#execute"
- example commit: https://bitbucket.org/RudineyFranceschi/cartax/commits/3e3e9ba360eade4ed89506cdf03937dee7b19e60/
- Copy the
ErrorHandlingMutation
mutation mixin - Copy the
BaseMutation
- Create the
Passenger
model with has_one :user - example commit: https://bitbucket.org/RudineyFranceschi/cartax/commits/cc5cc8c26f2dec585f25cceeceb39dcead1e4585/
- create the
passengerSignup
mutation - return a public version of the Passenger (
Types::Models::PublicPassengerType
) - example commit: https://bitbucket.org/RudineyFranceschi/cartax/commits/b1917b2f50bec9f9daea711afa91531d61d29a31/
- Add doorkeeper https://github.com/doorkeeper-gem/doorkeeper
- integrate with devise https://github.com/betterup/devise-doorkeeper
- Check both
devise.rb
&doorkeeper.rb
config - copy
UserTokenType
- copy
graphql/mutations/mixins/handle_login_mutation.rb
- Mutation to login ond return a token
- example commit: https://bitbucket.org/RudineyFranceschi/cartax/commits/36ea0bf4d55a8ca880390432b2675dbbe3af5f95/
- new graphql route & Schema
- simple
Me
query returning aPassengerType
- example commit: https://bitbucket.org/RudineyFranceschi/cartax/commits/15d4014c2356bdbc270a3985b78322a60e7d8917/
- locally install postgis:
brew install postgis
- gem: https://github.com/rgeo/activerecord-postgis-adapter
- heroku setup: https://devcenter.heroku.com/articles/postgis
- change rails database config:
- https://devcenter.heroku.com/articles/rails-database-connection-behavior
- url: <%= ENV.fetch('DATABASE_URL', '').sub(/^postgres/, "postgis") %>
- example with CheckPoints Table: https://bitbucket.org/RudineyFranceschi/cartax/commits/e13522267b5855f111cc6150cfd8ff0d6d94136e/
- FCM gem: https://github.com/spacialdb/fcm
- Copy PushNotification class
- Copy the Base Notification class
- be sure to have
ruby "2.5"
at Gemfile heroku apps:create cartax-staging --remote=staging
heroku buildpacks:add heroku/nodejs
heroku buildpacks:add heroku/ruby
heroku config:set BUNDLE_GITLAB__COM=devmaker-ci-cd:THE_SUPER_SECRET_PASSWORD
(if the project uses this gem from the private gitlab repo)heroku config:set RAILS_ENV=staging -a YYYY-staging
heroku config:set RAILS_MASTER_KEY=[master.key string] -a YYYY-staging
- create a
Procfile
file at root (maybe the first time you create the database you cant have therelease
Procfile line)web: bundle exec puma -C config/puma.rb release: bundle exec rake db:migrate
- Configure the heroku final url: (at production.rb or staging.rb)
Rails.application.routes.default_url_options = {host: "http://YOUR-APP-NAME-HERE.herokuapp.com"} config.action_mailer.default_url_options = Rails.application.routes.default_url_options config.action_controller.default_url_options = Rails.application.routes.default_url_options
- replace the default js_compressor to enable Uglyfier harmony mode:
config.assets.js_compressor = Uglifier.new(harmony: true)
- Create a staging rails env and set at the heroku staging app
- copy
config/production.rb
and change url - change the
database.yml
to set staging like prod
- copy
- set this to
staging.rb
andproduction.rb
:config.assets.js_compressor = Uglifier.new(harmony: true)
- After the deploy is done:
heroku run rake db:schema:load -a YYYYYYY
heroku run rake db:seed -a YYYYYYY
- Start understanding how Rails ActiveJob works: https://guides.rubyonrails.org/active_job_basics.html
- Instal redis in your machine (
brew install redis
?) - Add (or buy) the
Heroku Redis
addon to your heroku app - Add sidekiq and redis gems:
gem "redis", "~> 4.0" gem "sidekiq"
- Run
bundle install
- Tell Heroku to start a new process to run
sidekiq
by adding this toProcfile.dev
:worker: bundle exec sidekiq -e $RAILS_ENV -c 10
- Check if you have to pay for this new process at your heroku app
- Add
config.active_job.queue_adapter = :sidekiq
toconfig/application.rb
- Add the sidekiq web interface by adding
mount Sidekiq::Web => "/sidekiq"
toroutes.rb
- Require a username and password authentication for this ui in production:
- add this to the top of the
routes.rb
:
require 'sidekiq/web' Sidekiq::Web.use Rack::Auth::Basic do |username, password| ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(username), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_USERNAME"])) & ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_PASSWORD"])) end if Rails.env.production?
- add this to the top of the
- Add redis gem:
gem "redis", "~> 4.0"
- Run
bundle install
- Create NotificationsChannel (notifications_channel.rb) in app/channels
class NotificationsChannel < ApplicationCable::Channel def subscribed stream_for current_user end end
- Change the class Connection in channels/application_cable/connection.rb:
module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect self.current_user = find_verified_user logger.add_tags "ActionCable", current_user.id end protected def find_verified_user puts("verifying") verified_user = env["warden"].user || User.find_by(id: access_token&.resource_owner_id) verified_user || reject_unauthorized_connection end def access_token @access_token ||= Doorkeeper::AccessToken.by_token( request.query_parameters[:token] ) end end end
- Add the following configuration to the module Pattern in config/application.rb:
config.action_cable.disable_request_forgery_protection = true
-
You must have user authentication system and at least one registered user (in our example we name it user1 = User.find(1))
-
Configure the development adapter in
config/cable.yml
:development: adapter: redis url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> channel_prefix: {your-project}_development
-
Create a file
test.coffee
on the directoryapp/assets/javascripts
and add the following content to it:App.room = App.cable.subscriptions.create "NotificationsChannel", connected: -> console.log('connected') received: (data) -> console.log(data['message'])
-
Add the created
test.coffee
andcable.js
to theadmin.js
//= require cable.js //= require test.coffee
-
Login with user1 and open the browser console. If it displays "connected", the websocket is working.
-
Run
rails console
in the terminal and try sending a message to the user1ActionCable.server.broadcast_to user1, message: "hello user"
-
If the response to this command is "1", the message was sent by the websocket. Check if the message "hello user" arrived on the browser console opened earlier.