I guess this is my how-to build a rails app from scratch.
Using Rails 6.0.3.3, ElasticSearch (Searchkick), Sidekiq, Redis, PostgreSQL to build an app to utilize the data.
rails new baby_names -d postgresql -T
Adding Rspec.
# Add gem to Gemfile
gem 'rspec-rails'
# Run bundler
bundle install
# install rspec
rails g rspec:install
# test
rails test
# configure rspec spec/rails_helper.rb
...
require 'simplecov'
require 'simplecov-bamboo'
SimpleCov.start 'rails'
...
# my installation is unique to my setup
Adding Bootstrap, JQuery, Popper.js
yarn add bootstrap jquery popper.js
# edit config/webpack/environment.js
...
const webpack = require("webpack")
const customConfig = require('./custom');
environment.plugins.prepend("Provide", new webpack.ProvidePlugin({
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default'],
_: 'underscore'
}))
environment.config.merge(customConfig);
...
Load Bootstrap.css to Rails
# app/assets/stylesheets/application.css.scss add
*= require bootstrap
Database setup.
I use credentials, your setup might be different.
EDITOR="vi" rails credentials:edit
# my format looks like this
development:
postgres:
host: localhost
username: user
password: secret
test:
postgres:
host: localhost
username: user
password: secret
production:
postgres:
host: localhost
username: user
password: secret
My database.yml looks like this:
...
development:
<<: *default
host: <%= Rails.application.credentials.dig(:development, :postgres, :host) %>
username: <%= Rails.application.credentials.dig(:development, :postgres, :username) %>
password: <%= Rails.application.credentials.dig(:development, :postgres, :password) %>
database: baby_names_development
test:
<<: *default
host: <%= Rails.application.credentials.dig(:test, :postgres, :host) %>
username: <%= Rails.application.credentials.dig(:test, :postgres, :username) %>
password: <%= Rails.application.credentials.dig(:test, :postgres, :password) %>
database: baby_names_test
production:
<<: *default
host: <%= Rails.application.credentials.dig(:production, :postgres, :host) %>
username: <%= Rails.application.credentials.dig(:production, :postgres, :username) %>
password: <%= Rails.application.credentials.dig(:production, :postgres, :password) %>
database: baby_names_production
Create Database.
rails db:create
Create Home Page.
rails g controller Home index
# Added root route config/routes.rb
root to: 'home#index'
Create the Name and DataFiles Model.
rails g model Name name:string gender:string{1} amount:integer rank:integer year:integer
rails g model DataFile name:string
rails db:migrate
# If we care about duplicate entries for Names when we do an import that does not use ActiveRecord we can add an index like so:
add_index :names, [:name, :gender, :year], unique: true
Install ActiveStorage.
rails active_storage:install
rails db:migrate
Importing Data
I will be using Jobs, Sidekiq, Redis
Adding Sidekiq
# Gemfile
gem 'sidekiq'
bundle install
Mounting SideKiq::Web
# config/routes.rb
require 'sidekiq/web'
...
mount Sidekiq::Web => '/sidekiq'
...
# Now you can go to localhost:3000/sidekiq to view jobs
Create the ImportNames job.
rails g job ImportNames
Create a controller to upload files.
rails g controller ImportDataFiles index new
Adding and Using postgres-copy to import.
gem 'postgres-copy'
bundle install
Adding logic to the active job
class ImportNamesJob < ApplicationJob
queue_as :default
def perform(data_file = nil)
return nil unless data_file
data_file.csv_file.open(tmpdir: 'tmp/') do |file|
Name.copy_from file
end
end
end
Triggering the active job when file is uploaded.
# in the create method in the if @data_file.save block
ImportNamesJob.perform_later(@data_file)
I think this is the interesting part to this app the rest will be just graphs and charts. Look at the code and run the app.
rails s
sidekiq
I guess I can do a part 2 where it is just displaying names.