TOPシステム開発> RoRのデータ受け取り方法を修正する
いまが旬!Ruby on Rails&OpenLaszlo
いまが旬!Ruby on Rails&OpenLaszlo

第3回:Google Maps+Ruby on Railsで連携したアプリケーションを作る

著者:ネットエイト  十河 学   2007/10/15
前のページ  1  2  3  次のページ
RoRのデータ受け取り方法を修正する

   RoRのActiveResourceはPOSTされたデータのcontentTypeを識別します。「application/x-www-form- urlencoded」であればWebブラウザのフォームから、「application/xml」であればXMLデータとして自動的にハッシュに変換します。このためコントローラではどのタイプのデータでPOSTされたのか気にする必要はありません。

   しかしFlashでのContentTypeの設定はActionScript 3.0、FlashPlayer 9以上から可能となっており、Flash8以前のバージョンではContentTypeを設定することができません。そのためここでは汎用的に利用するため「lzdata」というパラメータを追加し、ここにXMLデータを設定しています。RoR側は「before_filter」を使用して「lzdata」があればXMLデータとしてハッシュ化するように設定します。

laszlodemo/app/controllers/application.rb
class ApplicationController < ActionController::Base
  before_filter :add_lzxdata_to_params
  # Pick a unique cookie name to distinguish our session data from
others'
  session :session_key => '_laszlodemo_session_id'

  def add_lzxdata_to_params
    if params.include?('lzdata')
      lzdata = Hash.from_xml(params[:lzdata]).with_indifferent_access
      params.update(lzdata);
    end
  end

end

   次に、XMLフォーマットでリクエストされた際の正常/異常をXML形式でレスポンスするため、customers_controllerのPOST/PUT/DELETEメソッドを次のように修正します。

laszlodemo/app/controllers/customers_controller.rb(一部)
 # POST /customers
  # POST /customers.xml
  def create
    @customer = Customer.new(params[:customer])

    respond_to do |format|
      if @customer.save
        flash[:notice] = 'Customer was successfully created.'
        format.html { redirect_to customer_url(@customer) }
        format.xml { render :xml => '<ok action="create" />' }
      else
        format.html { render :action => "new" }
        format.xml { render :xml => @customer.errors.to_xml }
      end
    end
  end

  # PUT /customers/1
  # PUT /customers/1.xml
  def update
    @customer = Customer.find(params[:id])

    respond_to do |format|
      if @customer.update_attributes(params[:customer])
        flash[:notice] = 'Customer was successfully updated.'
        format.html { redirect_to customer_url(@customer) }
        format.xml { render :xml => '<ok action="update" />' }
      else
        format.html { render :action => "edit" }
         format.xml { render :xml => @customer.errors.to_xml }
      end
    end
  end

  # DELETE /customers/1
  # DELETE /customers/1.xml
  def destroy
    @customer = Customer.find(params[:id])
      @customer.destroy

    respond_to do |format|
      format.html { redirect_to customers_url }
      format.xml { render :xml => '<ok action="delete" />' }
    end
  end

   それではLZXに戻り、保存と削除ボタンを追加したrestgridを作成しましょう。<attribute>タグでクラスのプロパティを設定します。ここでは「削除」「保存」ボタンのvisibleとRESTリクエストのURLをプロパティとして作成しました。

   次のコードでは新規データ作成用のパブリックメソッド「createdata」と内部で使用するためのプライベートメソッドを作成しています。プライベートメソッドには<!--- @keywords private -->コメントを追加してドキュメントに出力されないようにしています。ただしLZX言語ではprivateの概念がありませんので外部からアクセスすることは可能です。

   post/delete/put/getのアクションと対象となるオブジェクトのURLを指定してRESTリクエストするために、下のコード内のrequestメソッドが重要なメソッドとなっています。リクエストの結果をdatapointerでチェックし、異常の場合はデバッグウィンドウにエラーメッセージを表示、正常の場合はリクエストタイプによって必要な処理を追加しています。

restgrid.lzx
<library>
    <include href="gridbutton.lzx" />

    <!--- REST保存、削除機能が追加されたグリッド -->
    <class name="restgrid" extends="grid">
        <!--- リクエストベースURL -->
        <attribute name="baseurl" value="" type="string" />
        <!--- 保存ボタン表示 -->
        <attribute name="showsavebutton" type="boolean" value="true" />
        <!--- 削除ボタン表示 -->
        <attribute name="showdeletebutton" type="boolean" value="true" />

        <!--- @keywords private アクションされたデータポインタを保持 -->
        <attribute name="_actioneddp" value="null" />

        <!-- RESTリクエスト用のデータセット -->
        <dataset name="actionds" request="false" />

        <gridbutton text="保存" visible="${classroot.showsavebutton}">
            <handler name="onclick" args="dp">
                 classroot.updatedata(dp);
           </handler>
        </gridbutton>
        <gridbutton text="削除" visible="${classroot.showdeletebutton}">
           <handler name="onclick" args="dp">
                classroot.deletedata(dp);
           </handler>
        </gridbutton>

        <!--- 新規データ作成 -->
        <method name="createdata">
            this.request("post", "");
        </method>
        <!--- @keywords private データ削除 -->
        <method name="deletedata" args="dp">
            var nodeid = dp.xpathQuery("id/text()");
            this._actioneddp = dp;
           this.request("delete", nodeid + ".xml");
          </method>

        <!--- @keywords private データ更新 -->
        <method name="updatedata" args="dp"><![CDATA[
            var nodeid = dp.xpathQuery("id/text()");
            this._actioneddp = dp;
            this.request("put", nodeid + ".xml");
          ]]></method>

        <!--- @keyword private データリクエスト -->
        <method name="request" args="method, obj"><![CDATA[
            var p = new LzParam();

            switch(method){
             case "get": case "GET":
                this.actionds.setQueryType("get");
                break;
            case "post": case "POST":
                this.actionds.setQueryType("post");
                break;
            case "delete": case "DELETE":
                this.actionds.setQueryType("post");
                p.addValue("_method", "delete");
                break;
            case "put": case "PUT":
                this.actionds.setQueryType("post");
                p.addValue("_method", "put");
                p.addValue("lzdata", this._actioneddp.serialize());
                break;
            }
            p.addValue("format", "xml");

            this.actionds.setSrc(this.baseurl + obj);
            this.actionds.setQueryString(p);
            this.actionds.doRequest();
          ]]></method>
    </class>
</library>

*restgrid.lzxの「<!--- @keywords private データ削除 -->」の項目の前に、「<!--- 新規データ作成 -->」を追加訂正します。(2007/11/21)

前のページ  1  2  3  次のページ


株式会社ネットエイト 十河 学
著者プロフィール
株式会社ネットエイト  十河 学
2005年にOpenLaszloに出会う。RIAとオープンソースの可能性に感動し、OpenLaszloの情報交換を目的としたlaszlo.jpを勢いで開設。オープンソースアプリケーションはもちろん、iTunesやYouTubeから生まれるアーティストや、場所を問わないワークスタイルなどインターネットを中心として大きく変わりつつある世界の動きにも興味あり。現在はnet8のメンバーで沖縄県在住。

http://laszlo.jp


INDEX
第3回:Google Maps+Ruby on Railsで連携したアプリケーションを作る
  LZXのグリッドをグリッドをコンポーネント化する
RoRのデータ受け取り方法を修正する
  RoRのデータ受け取り方法を修正する(続き)