How to generate Rails models from database schemas

Yaay! I’m happy to report success with my first attempt to make a Rails
app that works from an existing database.

This first experiment used (a) the simplest “instructions” I could find
(basically, Hassan’s); (b) a streamlined version of the “Getting Started
Guide” process for setting up a Rails app (but - this is crucial -
omitting the step of running the migrator); and (c) a pre-existing
(“legacy”) database that conforms to the Rails naming conventions.

For the benefit of other Rails newbies (or oldbies) that need to build
apps
on existing DBs, a play-by-play of what I did follows.

  1. Created new Rails app, x:
    [sunward@web324 rails_eval]$ rails new x

  2. Populated the “legacy” SQLite database with table toys, and added one
    row to that table:
    [sunward@web324 x]$ rails dbconsole
    SQLite version 3.6.20
    sqlite> CREATE TABLE toys (“id” INTEGER PRIMARY KEY AUTOINCREMENT NOT
    NULL,
    “name” TEXT);
    sqlite> INSERT INTO toys (name) VALUES (“Tinker”);
    sqlite> SELECT * FROM toys;
    1|Tinker|58

  3. Added the *toys *resource and root to routes.rb:
    Rails.application.routes.draw do
    resources :toys
    root ‘toys#index’
    end

  4. Used *rake *to see the resulting routes:
    [sunward@web324 x]$ rake routes
    Prefix Verb URI Pattern Controller#Action
    toys GET /toys(.:format) toys#index
    POST /toys(.:format) toys#create
    new_toy GET /toys/new(.:format) toys#new
    edit_toy GET /toys/:id/edit(.:format) toys#edit
    toy GET /toys/:id(.:format) toys#show
    PATCH /toys/:id(.:format) toys#update
    PUT /toys/:id(.:format) toys#update
    DELETE /toys/:id(.:format) toys#destroy

  5. Generated *toys *controller:
    [sunward@web324 x]$ rails generate controller toys
    create app/controllers/toys_controller.rb
    invoke erb
    create app/views/toys
    invoke test_unit
    create test/controllers/toys_controller_test.rb
    invoke helper
    create app/helpers/toys_helper.rb
    invoke test_unit
    invoke assets
    invoke coffee
    create app/assets/javascripts/toys.coffee
    invoke scss
    create app/assets/stylesheets/toys.scss

  6. Added the necessary CRUD methods to the *toys *controller:
    class ToysController < ApplicationController
    def index
    @toys = Toy.all
    end

    def show
    @toy = Toy.find(params[:id])
    end

    def new
    @toy = Toy.new
    end

    def create
    @toy = Toy.new(toy_params)
    if @toy.save
    redirect_to @toy
    else
    render ‘new’
    end
    end

    def edit
    @toy = Toy.find(params[:id])
    end

    def update
    @toy = Toy.find(params[:id])
    if @toy.update(toy_params)
    redirect_to @toy
    else
    render ‘edit’
    end
    end

    def destroy
    @toy = Toy.find(params[:id])
    @toy.destroy

     redirect_to toys_path
    

    end

    private
    def toy_params
    params.require(:toy).permit(:name)
    end
    end

  7. Made* index.html.erb, show.html.erb, new.html.erb, edit.html.erb,
    _form.html.erb, index.json.jbuilder, show.json.jbuilder,* following the
    pattern in Getting Started with Rails — Ruby on Rails Guides.

  8. Created the *Toy *model file, toy.rb:
    class Toy < ActiveRecord::Base
    end

  9. In my browser, tried http://x.sunward.webfactional.com/toys. Feel
    free
    to try it yourself. (However, this is a temporary site that may be gone
    by
    the time you read this.) It works!!! That is, all the CRUDs execute
    as
    they should.

  10. An odd note is that there still is no schema.rb file in x/db/.
    If
    this is what Rails uses as its “database catalog”, is the lack of it
    going
    to cause trouble down the road?

Thanks again to Scott, Hassan, & Colin for your key clues.

My next question is whether it is possible to sue the amazing Rails
generators - in particular, scaffold - to more quickly create an app
that
works with an existing database - so it would not be necessary to go
thru
all those manual steps shown above. I tried it once, and it tried to
run
the migrator and croaked when it found that the DB table was already
there. But that may have been pilot error on my part. Comments and
advice
would be welcome.

~ Ken