とりあえず動く RubyAMF
RubyAMF とは
Flash と Rails の間でオブジェクトの相互変換を行ってくれるプラグイン。
サンプルでは Hello World の送信をしているくらいのものしかなかったので、モデルの情報を Flash 側から入力して Rails で受け取るまでの最小限のサンプルコード。例によって私が忘れたときの俺様用メモ。
導入
Rails のバージョンは 2.1.1 で確認。いつものようにプラグインをインストールします。
ruby script/plugin install http://rubyamf.googlecode.com/svn/trunk/
完了すると、 routes.rb に RubyAMF 用のルーティングが定義されるはずです。また、 RAILS_ROOT/config 以下に rubyamf_config.rb というファイルが作成されるので、これを編集します。
ClassMappings.translate_case = true
Ruby と AS の命名規則の差を埋めます。 created_at <=> createdAt への変換を行うという設定。
ClassMappings.assume_types = true
これを設定しないと、 Rails 側に送信される値がただのハッシュになります。true にすることで各種モデルのクラス(のようなもの)として送信されます。
ParameterMappings.scaffolding = true
これを true にしないと Rails 側で値を受け取るときに params[0] のような値を受け取る事になります。true にしても params[0] のような表記も使えるので、とりあえず true にします。
ここまで完了したら、今回操作するモデルを作成します。名前は Sample にして、持っている値は以下のとおり。
なお、 name という名前は AS の String 型のメンバと競合するようなので避けましょう。
- subject(String)
- body(String)
以上、設定終わり。
ActionScript を記述
続いて、一旦 ActionScript の記述に入ります。ファイルの配置は以下のとおり。
┌mainApp.mxml
├Sample.as
└as─sample.as
それぞれのファイルの中身を見ていきます。
mainApp.mxml
これがアプリケーションのメイン、入力フォーム。<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:comp="*" layout="absolute" backgroundColor="#000000" backgroundAlpha="0" > <!-- ここで sample.as を呼び出す事にして、スクリプトの中身は外に出す --> <mx:Script source="as/sample.as" /> <!-- ここで Rails 側と連携を行っている --> <mx:RemoteObject id="sampleService" destination="rubyamf" endpoint="http://localhost:3000/rubyamf_gateway/" source="SampleController" /> <!-- 送信メソッドは as/sample.as に記述済み --> <mx:Panel title="送信テスト" width="100%" height="100%"> <mx:VBox width="100%"> <mx:Form width="100%" height="500"> <mx:FormItem label="題名" required="true"> <mx:TextInput width="150" id="subject" /> </mx:FormItem> <mx:FormItem label="本文" required="true"> <mx:TextInput width="150" id="body" /> </mx:FormItem> <mx:Button label="作成" click="createSample()" /> </mx:Form> </mx:VBox> </mx:Panel> </mx:Application>
Sample.as
as 以下のファイルとは別なので注意。これは主に Rails のモデルに相当するクラスの情報を AS 向けに記述します。
package { [RemoteClass(alias="Sample")] public class Sample { // これは全部共通 public var id:int; public var errors:Object; // ここからは個別のデータ public var subject:String; public var body:String; } }
as/sample.as
先ほど外に出したスクリプト。主な処理はここで行います。
import mx.rpc.remoting.*; import mx.rpc.events.*; import mx.rpc.*; import mx.collections.ArrayCollection; import Sample; import mx.controls.Alert; import mx.controls.*; import mx.events.ListEvent; // モデルの作成 private function createSample():void { var sample:Sample = new Sample(); sample.subject = subject.text; sample.body = body.text; save(sample); // わかりやすいようにメッセージを表示する Alert.show("送信できました"); } // モデルの保存 private function save(sample:Sample):void { // ここで Rails の save メソッドを呼び出している var call:AsyncToken = sampleService.save({sample:sample}); call.addResponder(new mx.rpc.Responder(onSaveSuccess, onSaveFault)); } // 保存完了時 private function onSaveSuccess(e:ResultEvent):void { } private function onSaveFault(e:ResultEvent):void { }
Rails 側の記述
Rails 側では、値を受け取る SampleController を記述します。
今はとりあえず作成だけ。
class SampleController < ApplicationController # 保存 def save # ここでエラーになる場合 config の記述とサーバの再起動を確認 @sample = params[:sample] respond_to do |format| format.amf do if @sample.save render :amf => params[:sample] else render :amf => FaultObject.new(params[:sample].errors.join("/n")) end end end end end
以上、条件はすべてクリアした!
後は localhost の 3000 番ポート(設定により可変)でサーバを立ち上げて、 Flash アプリからデータを送信してみましょう。
上のサンプルでは確認用メソッドを記述していませんが、その辺りは適当にどうぞ。
参考
いつもお世話になっているちゅう君のサイト。サンプルソースもいただきました。
http://ecpplus.net/weblog/ruby/rubyamf/