WEB+DB No.73の記事よりRails 4に入門する 〜その2〜
前回のつづきです。
じゃあスキャフォからで。
お馴染みscaffold
前回入れたsprintgをrailsコマンドの代わりに使えば良い模様。
» spring generate scaffold book title price:integer Usage: spring COMMAND [ARGS] Commands for spring itself: binstub Generate spring based binstubs. help Print available commands. start Boot the spring server (this happens automatically when you run a command) status Show current status. stop Stop all spring processes for this project. Commands for your application: cucumber Execute a Cucumber feature. rails Run a rails command. The following sub commands will use spring: console, runner, generate. rake Run a rake task. rspec Execute an RSpec spec. testunit Execute a Test::Unit test.
あれ、spring {コマンド}のコマンドの部分にむしろrails って入れて、更にサブコマンドとしてgenerateを指定しろってことか・・・。
springのコマンド一覧より
rails console, rails generate, rails runner
These execute the rails command you already know and love. If you run a different sub command (e.g. rails server) then spring will automatically pass it through to the underlying rails executable (without the speed-up).
※springのコマンド一覧より
consoleとgenerateとrunner以外もrails *なコマンドは自動でパスを通すから、実行できるけど速度アップはしないよ、ってことでspring rails generateはスピードアップの恩恵に預かれるってことかな。
おそらく最近変わったのだと思われる。
ということで以下。
» spring rails generate scaffold book title price:integer invoke active_record create db/migrate/20130429114819_create_books.rb create app/models/book.rb invoke test_unit create test/models/book_test.rb create test/fixtures/books.yml invoke resource_route route resources :books invoke jbuilder_scaffold_controller create app/controllers/books_controller.rb invoke erb create app/views/books create app/views/books/index.html.erb create app/views/books/edit.html.erb create app/views/books/show.html.erb create app/views/books/new.html.erb create app/views/books/_form.html.erb invoke test_unit create test/controllers/books_controller_test.rb invoke helper create app/helpers/books_helper.rb invoke test_unit create test/helpers/books_helper_test.rb invoke jbuilder exist app/views/books create app/views/books/index.json.jbuilder create app/views/books/show.json.jbuilder invoke assets invoke coffee create app/assets/javascripts/books.js.coffee invoke scss create app/assets/stylesheets/books.css.scss invoke scss create app/assets/stylesheets/scaffolds.css.scss
色々つくってくれました〜。
app/controllers/books_controller.rbを覗いてみます。
class BooksController < ApplicationController # 一番下のprivateメソッドのところにあるset_bookを # show, edit, update, destroyを処理するときだけ # 事前に実行する before_action :set_book, only: [:show, :edit, :update, :destroy] # GET /books # GET /books.json def index # 本のレコード全部を表示する @books = Book.all end # GET /books/1 # GET /books/1.json def show # id指定されたものを表示する # なんと何も書かなくていいとは! end # GET /books/new def new @book = Book.new end # GET /books/1/edit def edit end # POST /books # POST /books.json def create @book = Book.new(book_params) respond_to do |format| # saveの成功判定をして分岐 if @book.save format.html { redirect_to @book, notice: 'Book was successfully created.' } format.json { render action: 'show', status: :created, location: @book } else format.html { render action: 'new' } format.json { render json: @book.errors, status: :unprocessable_entity } end end end # PATCH/PUT /books/1 # PATCH/PUT /books/1.json def update respond_to do |format| if @book.update(book_params) format.html { redirect_to @book, notice: 'Book was successfully updated.' } format.json { head :no_content } else format.html { render action: 'edit' } format.json { render json: @book.errors, status: :unprocessable_entity } end end end # DELETE /books/1 # DELETE /books/1.json def destroy @book.destroy respond_to do |format| format.html { redirect_to books_url } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_book # idの指定があれば値が入る @book = Book.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def book_params params.require(:book).permit(:title, :price) end end
DB作成
scaffoldでつくった定義をDBに反映する
spring rake db:migrate
できたか確認して見ましょう。
» sqlite3 db/development.sqlite3 sqlite> .schema CREATE TABLE "books" ( "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "price" integer, "created_at" datetime, "updated_at" datetime ); CREATE TABLE "schema_migrations" ( "version" varchar(255) NOT NULL ); CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version"); sqlite> .exit »
※見やすいように勝手にインデントしました。
ちゃんとできてるみたいですね!
テストを実行
チュートリアルもおもむろにテストを実行していたので実行してみます!
spring rake
結果はおもしろくなかったので割愛。
サーバー起動!
これはspringじゃないんですね!!
» rails s => Booting WEBrick => Rails 4.0.0.beta1 application starting in development on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2013-04-29 21:22:19] INFO WEBrick 1.3.1 [2013-04-29 21:22:19] INFO ruby 2.0.0 (2013-02-24) [x86_64-darwin11.4.2] [2013-04-29 21:22:19] INFO WEBrick::HTTPServer#start: pid=86260 port=3000
以下にアクセス!
http://localhost:3000/
はい、TOPはつまんないっすね。
次行きましょう。
http://localhost:3000/books
↓↓↓↓↓↓
↓↓↓↓↓↓
↓↓↓↓↓↓
↓↓↓↓↓↓
はい、CRUD全部できますね!
TOPページをbooksに
» vi config/routes.rb Tetsuzine::Application.routes.draw do resources :books root 'books#index' # 中略 end
はいこれで、http://localhost:3000/ にアクセスしてもbooksのページに行くはずです。
カラム追加を行う
booksにpublished_onを追加します。
railsコマンドを挟むのを忘れずに。
» spring rails generate migration add_published_on_to_books published_on:date invoke active_record create db/migrate/20130429123541_add_published_on_to_books.rb
続けてマイグレーションを実行します。
» spring rake db:migrate == AddPublishedOnToBooks: migrating ========================================== -- add_column(:books, :published_on, :date) -> 0.0174s == AddPublishedOnToBooks: migrated (0.0175s) =================================
確認しましょう!
» sqlite3 db/development.sqlite3 sqlite> .schema CREATE TABLE "books" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "price" integer, "created_at" datetime, "updated_at" datetime, "published_on" date);
出来てますね!
今度はViewをいじってpublished_onを追加できるようにしましょう。
おそらく"title"というワードが入ってるファイルは全部編集した方がよさそうでね。
# grepで検索(rはサブディレクトリも含め再帰で検索、lはファイルのリストだけ表示にする) » grep -rl 'title' app/views/books/ app/views/books/_form.html.erb app/views/books/index.html.erb app/views/books/index.json.jbuilder app/views/books/show.html.erb app/views/books/show.json.jbuilder
以外にいっぱいありますね(^q^)
# 大文字のoオプションで立て区切りで複数ファイルを開いて編集する » vi -O `grep -rl 'title' app/views/books/`
htmlの方だけ画像で変更箇所を貼っておきます。
ブルーでハイライトされている部分だけ編集しています。
またcontrollerにあるStrongParametersの部分にもpublished_onを追加しないとですね。
(これなしで実行するとフォームはあっても値の入力ができないらしい)
» vi app/controllers/books_controller.rb def book_params params.require(:book).permit(:title, :price, :published_on) end
実際に投稿してみましょう。
デリミタ無しで続けて年月日を入力します。
やった!ちゃんとDATE型で保存できているようです!
ということで今回はここまでにしましょう!
残すはActiveModelとAjaxです!
つづく