6.2 Iteration A2: Making Prettier Listings 2 Instant Gratification
This section mostly covers database configuration options for those users that insist on using MySQL. SQLite3 users will skip most of it.
Create the application.
bundle exec /home/rubys/git/rails/railties/exe/rails new depot --skip-bundle --skip-listen
create
create README.md
create Rakefile
create .ruby-version
create config.ru
create .gitignore
create Gemfile
run git init from "."
Initialized empty Git repository in /home/rubys/git/awdwr/edition4/work/depot/.git/
create package.json
create app
create app/assets/config/manifest.js
create app/assets/javascripts/application.js
create app/assets/javascripts/cable.js
create app/assets/stylesheets/application.css
create app/channels/application_cable/channel.rb
create app/channels/application_cable/connection.rb
create app/controllers/application_controller.rb
create app/helpers/application_helper.rb
create app/jobs/application_job.rb
create app/mailers/application_mailer.rb
create app/models/application_record.rb
create app/views/layouts/application.html.erb
create app/views/layouts/mailer.html.erb
create app/views/layouts/mailer.text.erb
create app/assets/images/.keep
create app/assets/javascripts/channels
create app/assets/javascripts/channels/.keep
create app/controllers/concerns/.keep
create app/models/concerns/.keep
create bin
create bin/bundle
create bin/rails
create bin/rake
create bin/setup
create bin/update
create bin/yarn
create config
create config/routes.rb
create config/application.rb
create config/environment.rb
create config/cable.yml
create config/puma.rb
create config/spring.rb
create config/storage.yml
create config/environments
create config/environments/development.rb
create config/environments/production.rb
create config/environments/test.rb
create config/initializers
create config/initializers/application_controller_renderer.rb
create config/initializers/assets.rb
create config/initializers/backtrace_silencers.rb
create config/initializers/cookies_serializer.rb
create config/initializers/cors.rb
create config/initializers/filter_parameter_logging.rb
create config/initializers/inflections.rb
create config/initializers/mime_types.rb
create config/initializers/new_framework_defaults_5_2.rb
create config/initializers/wrap_parameters.rb
create config/locales
create config/locales/en.yml
create config/master.key
create config/boot.rb
create config/database.yml
create db
create db/seeds.rb
create lib
create lib/tasks
create lib/tasks/.keep
create lib/assets
create lib/assets/.keep
create log
create log/.keep
create public
create public/404.html
create public/422.html
create public/500.html
create public/apple-touch-icon-precomposed.png
create public/apple-touch-icon.png
create public/favicon.ico
create public/robots.txt
create test/fixtures
create test/fixtures/.keep
create test/fixtures/files
create test/fixtures/files/.keep
create test/controllers
create test/controllers/.keep
create test/mailers
create test/mailers/.keep
create test/models
create test/models/.keep
create test/helpers
create test/helpers/.keep
create test/integration
create test/integration/.keep
create test/test_helper.rb
create test/system
create test/system/.keep
create test/application_system_test_case.rb
create storage
create storage/.keep
create tmp/storage
create tmp/storage/.keep
exist tmp
create tmp/.keep
create tmp/cache
create tmp/cache/assets
create vendor
create vendor/.keep
remove config/initializers/cors.rb
remove config/initializers/new_framework_defaults_5_2.rb
Active Storage installation was skipped. Please run `bin/rails active_storage:install` to install Active Storage files.
bundle install --local
Resolving dependencies...
Using rake 12.2.1
Using concurrent-ruby 1.0.5
Using i18n 0.9.1
Using minitest 5.10.3
Using thread_safe 0.3.6
Using tzinfo 1.2.4
Using activesupport 5.2.0.alpha from source at `/home/rubys/git/rails`
Using builder 3.2.3
Using erubi 1.7.0
Using mini_portile2 2.3.0
Using nokogiri 1.8.1
Using rails-dom-testing 2.0.3
Using crass 1.0.2
Using loofah 2.1.1
Using rails-html-sanitizer 1.0.3
Using actionview 5.2.0.alpha from source at `/home/rubys/git/rails`
Using rack 2.0.3
Using rack-test 0.7.0
Using actionpack 5.2.0.alpha from source at `/home/rubys/git/rails`
Using nio4r 2.1.0
Using websocket-extensions 0.1.3
Using websocket-driver 0.6.5
Using actioncable 5.2.0.alpha from source at `/home/rubys/git/rails`
Using globalid 0.4.1
Using activejob 5.2.0.alpha from source at `/home/rubys/git/rails`
Using mini_mime 1.0.0
Using mail 2.7.0
Using actionmailer 5.2.0.alpha from source at `/home/rubys/git/rails`
Using activemodel 5.2.0.alpha from source at `/home/rubys/git/rails`
Using arel 9.0.0.alpha from source at `/home/rubys/git/arel`
Using activerecord 5.2.0.alpha from source at `/home/rubys/git/rails`
Using activestorage 5.2.0.alpha from source at `/home/rubys/git/rails`
Using public_suffix 3.0.1
Using addressable 2.5.2
Using io-like 0.3.0
Using archive-zip 0.7.0
Using bindex 0.5.0
Using msgpack 1.1.0
Using bootsnap 1.1.5
Using bundler 1.16.0
Using byebug 9.1.0
Using xpath 2.1.0
Using capybara 2.15.4
Using ffi 1.9.18
Using childprocess 0.8.0
Using chromedriver-helper 1.1.0
Using coffee-script-source 1.12.2
Using execjs 2.7.0
Using coffee-script 2.4.1
Using method_source 0.9.0
Using thor 0.19.4
Using railties 5.2.0.alpha from source at `/home/rubys/git/rails`
Using coffee-rails 4.2.2
Using et-orbi 1.0.8
Using multi_json 1.12.2
Using jbuilder 2.7.0
Using mono_logger 1.1.0
Using mustermann 1.0.1
Using pg 0.19.0
Using puma 3.10.0
Using queue_classic 3.2.0.RC1 from source at `/home/rubys/git/queue_classic`
Using rack-protection 2.0.0
Using sprockets 3.7.1
Using sprockets-rails 3.2.1
Using rails 5.2.0.alpha from source at `/home/rubys/git/rails`
Using rb-fsevent 0.10.2
Using rb-inotify 0.9.9 from source at `/home/rubys/git/rb-inotify`
Using redis 4.0.1
Using redis-namespace 1.6.0
Using tilt 2.0.8
Using sinatra 2.0.0
Using vegas 0.1.11
Using resque 1.27.4
Using rufus-scheduler 3.4.2
Using resque-scheduler 4.3.0 from source at `/home/rubys/git/resque-scheduler`
Using rubyzip 1.2.1
Using sass-listen 4.0.0
Using sass 3.5.3
Using sass-rails 5.0.6 from source at `/home/rubys/git/sass-rails`
Using selenium-webdriver 3.7.0
Using spring 2.0.2
Using sqlite3 1.3.13
Using turbolinks-source 5.0.3
Using turbolinks 5.0.1
Using uglifier 3.2.0
Using web-console 3.5.1 from source at `/home/rubys/git/web-console`
Bundle complete! 20 Gemfile dependencies, 86 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Look at the files created.
ls -p
app/ config.ru Gemfile.lock package.json README.md tmp/
bin/ db/ lib/ public/ storage/ vendor/
config/ Gemfile log/ Rakefile test/
Generate scaffolding for a real model, modify a template, and do our first bit of data entry.
Generating our first model and associated scaffolding
rails generate scaffold Product title:string description:text image_url:string price:decimal
invoke active_record
create db/migrate/20171113144039_create_products.rb
create app/models/product.rb
invoke test_unit
create test/models/product_test.rb
create test/fixtures/products.yml
invoke resource_route
route resources :products
invoke scaffold_controller
create app/controllers/products_controller.rb
invoke erb
create app/views/products
create app/views/products/index.html.erb
create app/views/products/edit.html.erb
create app/views/products/show.html.erb
create app/views/products/new.html.erb
create app/views/products/_form.html.erb
invoke test_unit
create test/controllers/products_controller_test.rb
create test/system/products_test.rb
invoke helper
create app/helpers/products_helper.rb
invoke test_unit
invoke jbuilder
create app/views/products/index.json.jbuilder
create app/views/products/show.json.jbuilder
create app/views/products/_product.json.jbuilder
invoke assets
invoke coffee
create app/assets/javascripts/products.coffee
invoke scss
create app/assets/stylesheets/products.scss
invoke scss
create app/assets/stylesheets/scaffolds.scss
Break lines for formatting reasons
edit app/controllers/products_controller.rb
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
@products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
@product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
@product = Product.new(product_params)
respond_to do |format|
if @product.save
format.html { redirect_to @product,
notice: 'Product was successfully created.' }
format.json { render :show, status: :created,
location: @product }
else
format.html { render :new }
format.json { render json: @product.errors,
status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if @product.update(product_params)
format.html { redirect_to @product,
notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: @product }
else
format.html { render :edit }
format.json { render json: @product.errors,
status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
@product.destroy
respond_to do |format|
format.html { redirect_to products_url,
notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
@product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white
# list through.
def product_params
params.require(:product).permit(:title, :description, :image_url, :price)
end
end
edit app/views/products/index.html.erb
<p id="notice"><%= notice %></p>
<h1>Products</h1>
<table>
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Image url</th>
<th>Price</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @products.each do |product| %>
<tr>
<td><%= product.title %></td>
<td><%= product.description %></td>
<td><%= product.image_url %></td>
<td><%= product.price %></td>
<td><%= link_to 'Show', product %></td>
<td><%= link_to 'Edit', edit_product_path(product) %></td>
<td><%= link_to 'Destroy', product,
method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Product', new_product_path %>
Add precision and scale to the price
edit db/migrate/20171113144039_create_products.rb
class CreateProducts < ActiveRecord::Migration[5.2]
def change
create_table :products do |t|
t.string :title
t.text :description
t.string :image_url
t.decimal :price, precision: 8, scale: 2
t.timestamps
end
end
end
Apply the migration
rails db:migrate
mv 20171113144039_create_products.rb 20171113000001_create_products.rb
== 20171113000001 CreateProducts: migrating ===================================
-- create_table(:products)
-> 0.0005s
== 20171113000001 CreateProducts: migrated (0.0005s) ==========================
Get an (empty) list of products
get /products
get /products/new
Show (and modify) one of the templates produced
edit app/views/products/_form.html.erb
<%= form_with(model: product, local: true) do |form| %>
<% if product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(product.errors.count, "error") %>
prohibited this product from being saved:</h2>
<ul>
<% product.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :title %>
<%= form.text_field :title, id: :product_title %>
</div>
<div class="field">
<%= form.label :description %>
<%= form.text_area :description, id: :product_description, rows: 10, cols: 60 %>
</div>
<div class="field">
<%= form.label :image_url %>
<%= form.text_field :image_url, id: :product_image_url %>
</div>
<div class="field">
<%= form.label :price %>
<%= form.text_field :price, id: :product_price %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
Create a product
get /products/new
get /products/new
post /products
get http://localhost:3000/products/1
Product was successfully created.
Title: Seven Mobile Apps in Seven Weeks
Description: <p> <em>Native Apps, Multiple Platforms</em> Answer the question “Can we build this for ALL the devices?” with a resounding YES. This book will help you get there with a real-world introduction to seven platforms, whether you’re new to mobile or an experienced developer needing to expand your options. Plus, you’ll find out which cross-platform solution makes the most sense for your needs. </p>
Image url: 7apps.jpg
Price: 29.0
Edit | BackVerify that the product has been added
get /products
Title | Description | Image url | Price | |||
---|---|---|---|---|---|---|
Seven Mobile Apps in Seven Weeks | <p> <em>Native Apps, Multiple Platforms</em> Answer the question “Can we build this for ALL the devices?” with a resounding YES. This book will help you get there with a real-world introduction to seven platforms, whether you’re new to mobile or an experienced developer needing to expand your options. Plus, you’ll find out which cross-platform solution makes the most sense for your needs. </p> | 7apps.jpg | 29.0 | Show | Edit | Destroy |
And, just to verify that we haven't broken anything
rails test
Run options: --seed 56475
# Running:
.......
Finished in 0.367772s, 19.0335 runs/s, 24.4717 assertions/s.
7 runs, 9 assertions, 0 failures, 0 errors, 0 skips
6.2 Iteration A2: Making Prettier Listings 2 Instant Gratification