リクエスト

基本

  • 基本は、「params[:パラメータ名]」で取得するだけ。
    • POSTもGETもルートパラメータ([/books/1]の[1]の部分ね)も一緒。

配列とハッシュ

  • 配列はこんなんで
    • URL的には、こんな感じで、パラメータの後に[]を付ける
      http://localhost:3000/ctrl/param_array?category[]=abc&category[]=test
      
    • すると、コントローラ(ctrl_controller.rb)でこう書けば、
      class CtrlController < ApplicationController
       def param_array
         render :text => "categoryのパラメータ" + params[:category].inspect
       end
      end
      
    • こう表示される
      categoryのパラメータ["abc", "test"]
      
  • ハッシュだと、paramsの後に[サブパラメータ]を付ける感じね
    • URLは、こんな感じねー
      http://localhost:3000/ctrl/param_array?category[param1]=abc&category[param2]=test
      
      • すると、こう表示される
        categoryのパラメータ{"param1"=>"abc", "param2"=>"test"}
        
      • コントローラ側では、「params[:param1]」みたいにサブパラメータにコロンを付けて取得ね
    • おおー、しかも2次元でも書けるんだ!
      http://localhost:3000/ctrl/param_array?category[param1][param1-1]=abc&category[param1][param1-2]=def&category[param2][param2-1]=test
      
      • 表示はこんな感じね。
        categoryのパラメータ{"param1"=>{"param1-1"=>"abc", "param1-2"=>"def"}, "param2"=>{"param2-1"=>"test"}}
        

パラメータ種別毎の取得方法

  • 当然、それぞれのパラメータ種別毎にも取得できる(けど、普通は使わないだろうなー)
    query_parameters GET→なんでget_parametersじゃないんだろ?
    request_parameters POST
    path_parameters ルートパラメータ
    • 例えば、query_parametersの場合、コントローラ側にこう書いて、
       def query_params
         render :text => "categoryのパラメータ" + request.query_parameters[:category].inspect
       end
      
    • こんなURLを叩くと、
      http://localhost:3000/ctrl/query_params?category[param1]=abc&category[param2]=test
      
    • こう表示される、と。
      categoryのパラメータ{"param1"=>"abc", "param2"=>"test"}
      

ヘッダ情報の取得

  • ヘッダ情報も取れる。って当たり前かw
    • コントローラで、こう書けば、
       def request_agent
         render :text => "User-Agent:" + request.headers['User-Agent']
       end
      
    • こんな感じで表示(これだと、chomeね)
      User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7
      
      • headersメソッドは、ヘッダ情報だけじゃなくて、サーバの環境変数も取れるんだ。
      • しかも、headersメソッド内では、リクエストヘッダ名は「HTTP_」で始まる値だけど大文字も区別しないから、"User-Agnet"でも"HTTP_USER_AGENT"でも同じものが取れるみたい
  • ヘッダ情報は専用の取得メソッドがあるから、できるだけこっちを使うのが吉かな
    • 主要なメソッドを実際に動かしたら、こんな感じの戻り値だった。
      メソッド名 概要     戻り値
      accept クライアントがサポートしてるコンテンツの種類 text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
      authorization 認証情報
      body 生のポストデータ   #
      content_length コンテンツのサイズ  0
      fullpath リクエストのURL   /ctrl/request_methods?param1=val1
      get? HTTP GETか?     true
      post? POSTか?(put/delete/headもあり) false
      host ホスト名       localhost
      host_with_port ポート付きのホスト名 localhost:3000
      local? ローカル通信か?   true
      method HTTPメソッド     GET
      port ポート番号      3000
      port_string ポート番号の文字列  :3000
      protocol プロトコル      http://
      remote_ip クライアントのIP   127.0.0.1
      request_method RailsのHTTPメソッド GET
      scheme スキーマ名      http
      server_software サーバのソフトウェア webrick
      ssl? SSLか?       false
      standard_port? Well-knownポートであるか? false
      url 完全なURL      http://localhost:3000/ctrl/request_methods?param1=val1
      xml_http_request? XmlHttpRequestオブジェクトであるか?
      • うーん、request_uriは動かん…。メソッドが無くなったのかな?
      • xml_http_request?は、メソッドはあるみたいだけど、結果が返ってこない?

アップロード

  • アップロードの基本は、ビュー側では、form側でmultipartをtrueにして、file_field_tagを使って設定して、コントローラ側ではparamsで取得するだけ
  • 一番シンプルに書くと、これだけでファイルが取得可能
    • ビュー側(upload.html.erb)は、こんな感じ
      <%= form_tag( { :action => "upload_process" }, :multipart => true) do %>
        <label>ファイルを指定:<%= file_field_tag "upfile" , { :size => 50 } %></label>
        <%= submit_tag "アップロード" %>
      <% end %>
      
    • で、コントローラ側(ctrl_controller.rb)はこんな感じ
       def upload_process
         file = params[:upfile]
         File.open("public/docs/test.txt","wb") { |f| f.write(file.read) }
         render :text => "アップロードしました"
       end
      
    • これで、画面でファイルを指定して「アップロード」ボタンを押すと、「public/docs/test.txt」に指定ファイルの中身が出力される
    • これだと、出力ファイルが固定だし、文字コードもなんも考えてないし、ファイルの妥当性もチェックしてないから、まずいんだよねw
  • まあ、ファイルの妥当性をチェックして、ファイル名もそのまま保存するコードだと、こんな感じみたい
     def upload_process
       file = params[:upfile]
       name = file.original_filename
       perms = ['.jpg','.jpeg','.gif','.png']
       if !perms.include?(File.extname(name).downcase)
         result = "アップロードできるのは画像ファイルだけです"
       elsif file.size > 1.megabyte
         result = "ファイルサイズは1Mバイトまでです"
       else
         File.open("public/docs/#{name}","wb") { |f| f.write(file.read) }
         result = "#{name}をアップロードしました"
       end
       render :text => result
     end
    
    • ここの「params[:upfile]」で取れるのは、TempFileオブジェクトなんで、いろいろな情報が取れるんだねー。
      original_filename ファイル名
      content_type コンテンツタイプ
      size ファイルサイズ
      read ファイルの内容の取得
    • というか、if文の凝縮度、すごいなー。「1.megabyte」とかの記述もイカス!
    • 日本語のファイル名とかだとおかしくなるけど、まあ、ここではいっかw
    • それに、モデルを使ったDB保存の例とかあるけど、そっちもまあいいやww
-
最終更新:2011年12月28日 10:53