Scaffolding

  • Scaffolding(スキャフィールディング)を使ってみよう!
    • まずは、作っちゃったモデルとかを削除
      • モデルの削除は、destoryで
        rails destroy model book
        
      • DBの削除も[rake]で
        rake db:drop
        
    • で、scaffoldでモデル等を生成
      rails g scaffold book isbn:string title:string price:integer publish:string published:date cd:boolean
      
      • 単にモデル作る時のコマンドが、modelからscaffoldになっただけ
    • モデルとかができたら、後はテーブル作成すればOK!
      rake db:migrate
      
    • 後は、URL叩けばActiveRecordにいきなりアクセス可能!こりゃ簡単だ!すごいね!
      http://localhost:3000/books
      
    • Scaffoldingで作られたルートって、結構すごいよ。
      • 実は、config/routes.rbには以下の記述があるだけ。
          resources :books
        
      • でも、これ結構いろいろやってくれるらしい。[rake routes]で確認すると…?
        C:\user\dev\railbook>rake routes
            books GET    /books(.:format)                       {:action=>"index", :controller=>"books"}
                  POST   /books(.:format)                       {:action=>"create", :controller=>"books"}
         new_book GET    /books/new(.:format)                   {:action=>"new", :controller=>"books"}
        edit_book GET    /books/:id/edit(.:format)              {:action=>"edit", :controller=>"books"}
             book GET    /books/:id(.:format)                   {:action=>"show", :controller=>"books"}
                  PUT    /books/:id(.:format)                   {:action=>"update", :controller=>"books"}
                  DELETE /books/:id(.:format)                   {:action=>"destroy", :controller=>"books"}
                         /:controller(/:action(/:id(.:format)))
        
      • とまあ、基本的なbooksへのアクセスルートを設定してくれるんだ!すごいね、これ。

Scaffoldingの各アクション

  • アクションは例によって、[app/controllers/books_controller.rb]ですね。
  • index(一覧)
    • 短い割には、意外に色々詰まってるindexのアクションメソッド
       def index
         @books = Book.all
         respond_to do |format|
           format.html # index.html.erb
           format.json { render json: @books }
         end
       end
      
    • 上記のrespond_toでフォーマット毎の出力をするらしい。
    • 普通はHTMLなんでindex.html.erbで表示して、[http://localhost:3000/books.json]みたいだとJSON形式で表示
    • でテンプレートでは、ついにヘルパーがお出まし
      • link_toではリンクを生成(そりゃそうかw)
      • テンプレート側がこうだと、
        <%= link_to 'New Book', new_book_path %>
        
      • 出力HTMLはこんな感じ
        <a href="/books/new">New Book</a>
        
      • new_book_pathは、ルート定義されたビューヘルパーなんだ!他にもいろいろ自動生成されてるよ。
    • これ、すげーな。
         <td><%= link_to 'Show', book %></td>
      
      • って書くと、渡されたbookオブジェクトを元に、[book.id]を取得しようとして、自動でIDを降ってこんな感じでHTML出力される!
           <td><a href="/books/1">Show</a></td>
        
    • 確認画面も簡単に出せるんだ!
          <td><%= link_to 'Destroy', book, confirm: 'Are you sure?', method: :delete %></td>
      
      • へー。出力結果を見ると、data-confirmが定義されてるだけなのか。
            <td><a href="/books/1" data-confirm="Are you sure?" data-method="delete" rel="nofollow">Destroy</a></td>
        
      • これが、Rails3の 控えめなJavaScript(Unobtrusive JavaScript) ってことなんだねー。
  • show(詳細表示)
    • アクションだと、params[:id]で、URLの[/books/1]の1を取れる。この形式でリクエストも取れるらしい。
         @book = Book.find(params[:id])
      
  • new/create(登録)
    • newは新規登録画面を出すアクションで、createは実際の登録のアクションだね。
    • あれ?newのテンプレートに、formの記述がこれしかない…
      <%= render 'form' %>
      
      • おおー、実体は[_form.html.erb]の方なんだ。
      • なるほどね。登録と更新でほとんど一緒のformだから、部分テンプレートにしてるのか。かしこいなー。
    • うお!createでのパラメタ取得、めちゃくちゃ簡単なんだ!
         @book = Book.new(params[:book])
      
      • これだけで、bookオブジェクトでき上がりとは…。
      • この場合、params[:book]で、フォームのbook[***]の値を全部取ってくるらしい。
      • 後は、@book.save で登録するだけか…。なんと簡単な…。
    • Scaffoldingのcreateメソッドでは、ちゃんと登録済み確認して、redirect_toでnoticeを出すらしい。
       def create
         @book = Book.new(params[:book])
         respond_to do |format|
           if @book.save
             format.html { redirect_to @book, notice: 'Book was successfully created.' }
             format.json { render json: @book, status: :created, location: @book }
           else
             format.html { render action: "new" }
             format.json { render json: @book.errors, status: :unprocessable_entity }
           end
         end
       end
      
      • あ、ここで指定したnoticeが、show.html.erbの一番上のnoticeに出るわけねー。良くできてるわ。
        <p id="notice"><%= notice %></p>
        
      • しかも、エラー時は@bookをそのまま使ってnew画面を出すから、入力データはそのまま表示されるのか!あったまいい!
  • edit/update(更新)
    • editアクションはパラメタからID取って表示するだけ。
    • updateアクションも、基本の構造はcreateと一緒。違うのは@book.saveじゃなくて、@book.update_attributesを使うってとこ。
       def update
         @book = Book.find(params[:id])
         respond_to do |format|
           if @book.update_attributes(params[:book])
             format.html { redirect_to @book, notice: 'Book was successfully updated.' }
             format.json { head :ok }
           else
             format.html { render action: "edit" }
             format.json { render json: @book.errors, status: :unprocessable_entity }
           end
         end
       end
      
      • @book.update_attributesは内部的にsaveを呼んでるから、savaのコールは不要
      • JSONでの更新成功時にある[head :ok]は、HTTPのステータスのみでコンテンツなしを返す便利メソッド。ここでは[200 OK]を返すって訳
        format.json { head :ok }
        
    • edit.html.erbは、newとeditで共通の部分テンプレートだけど、結構面白い。
      <%= form_for(@book) do |f| %>
      
      • このform_forって、オブジェクトが空だとその後の出力がいろいろと変化するらしい。
        ------------- 空(new) 値あり(edit)
        送信先アドレス /books /books/1
        HTTPメソッド post put(疑似)
      • 実際にはputはブラウザが対応してないから、hiddenで[name="_method" value="put"]って書いて、Railsで疑似ってるんだー
      • まあ、なんか面倒だけど例の「RESTfulインタフェース」の方針に従っての実装なんだねー。つうか、ブラウザ頑張れよってことかw
  • destroy(削除)
    • 削除は、単に@book.destroyするだけ。
       def destroy
         @book = Book.find(params[:id])
         @book.destroy
         respond_to do |format|
           format.html { redirect_to books_url }
           format.json { head :ok }
         end
       end
      
      • ここでも、JSON時は[head :ok]のみ返す感じ。

-
最終更新:2011年12月22日 07:28