RestfulXのScaffoldについて

RestfulXのScaffoldはmodel.ymlに様々な関係を定義し,一気に作成できます.
1.2.2からは,間違ったものも直せるようになりました.

しかし,ドキュメントがなく,ポリモーフィック関連等で困っていました.
調べてみると,「schema_to_yaml」を利用している模様です.

なので,以下のgithubに詳しく書いてありました.

http://github.com/malkomalko/schema_to_yaml/blob/c60b4dfbd568730b38479ff82cd90eabc4e2f589/README.rdoc

例は以下になります.

model1:
- aaa: string
- bbb: integer
- ccc: date
- ddd: datetime
- eee: boolean
- has_one: [model2]
- has_many: [model3s,model4s]
- belongs_to: [model5]
- polymorphic [model6]
- has_many_through: [permissions,roles]
- tree_model: [parent] *acts_as_category用のフィールド
- attachment_field: [image] * AttachmentFu用のフィールド生成
- layout: [default]
- ignored_fields: [aaa]

RestfulXソースコード分析

今回はRestfulXのソースコード読んで今までの導入で疑問に思ったことを解析します.
ソースコードGitHub - dima/restfulx_framework: The RESTful way to develop Adobe Flex and AIR applications.より入手できます.

疑問点は

  • rails側と接続するメソッドindex, create, update, destroyを行うときrails側へ他のパラメタを送信できるのか.
  • flex側でrailsと通信するときのURLを指定しないのどういうことか.

です.

ヒントはorg.restfulx.services.http.XMLHTTPServiceProviderに有りました.

function index(object:Object, responder:IResponder, metadata:Object = null, nestedBy:Array = null):void
function create(object:Object, responder:IResponder, metadata:Object = null, nestedBy:Array = null, recursive:Boolean = false, undoRedoFlag:int = 0):void
function update(object:Object, responder:IResponder, metadata:Object = null, nestedBy:Array = null, recursive:Boolean = false, undoRedoFlag:int = 0):void
function index(object:Object, responder:IResponder, metadata:Object = null, nestedBy:Array = null, recursive:Boolean = false, undoRedoFlag:int = 0):void

のmetadata:Objectに変数を格納してやるとrails側で受け取ることが出来ました.

またflexrailsと通信するときはhttp://以降から書く必要がないようなので

var httpService:HTTPService = new HTTPService();
httpService.url = "/" + 「コントローラー名」+ "/" +「メソッド名」

にておkでした.

Restfulx導入記 -その3 AdvancedDataGrid編-

前回までで何となく概要が分かったの勝手にカスタマイズしていきます.

前回の要約で,ツリー表示ができるよという記述がきになったので,今回と次回で,
Unitというmodelの表とツリー表示を行ってみたいと思います.
完成形はこんな感じです.


まずは,下準備としてacts_as_treeをインストール

ruby script/plugin install http://dev.rubyonrails.org/svn/rails/plugins/acts_as_tree

で,次に例のmodel.ymlを作ります.
今回はこんな感じで.作りました.

unit:
- name: string
- parent_id: integer
- deleted_at: datetime


さっそく,scaffoldとmigrateとbuildです.

./script/generate rx_yaml_scaffold
rake db:reset
rake db:flex:builder

で,雛形は完成です.

さて,直していきましょう.
app/models/unit.rbにて,acts_as_treeを加筆

class Unit < ActiveRecord::Base
acts_as_tree
end

次に,app/flex/プロジェクト名/models/Unit.as

package quickscope3.models {
import org.restfulx.models.RxTreeModel;

[Resource(name="units")]
[Bindable]
public class Unit extends RxTreeModel {
public static const LABEL:String = "name";
public var name:String = "";

[BelongsTo]
public var parent:Unit;

public function Unit() {
super(LABEL);
}
}
}

本家のチュートリアルは微妙に間違いがある(RxTreeModelがRubossTreeModelになっている)ので気をつけましょう.

さて,下準備が終わったので,AdvancedDataGridに表示してみましょう.
app/flex/プロジェクト名/components/generated/UnitBox.mxml
の最初のPanelをListからAdvancedDataGridに書き替えればOKです.















なお,childrenというのは,RxTreeModelで定義されているメソッドです(http://dima.github.com/restfulx_framework/
これで完成です.

ポイントを2点
app/flex/プロジェクト名/models/Unit.asにて,

  1. RxModelからRxTreeModelに変更すること
  2. Rx.models.index(Unit)

を理解することくらいです.
Rx.models.index(Unit)で,Unitの全データが持ってこれます.

次回はツリー表示に挑戦です.

Restfulx導入記 -その4 Tree編-

前回に引き続き,UnitというmodelのTree表示を行いたいと思います.

実は,Tree表示は結構面倒だったりします.
Rx.models.indexはModelsCollectionを返します.
ModelsCollection < RxCollection < mx.collections.ArrayCollection
な感じで,ArrayCollectionを継承したClassです.

つまり,Unit.find(:all) → Rx.models.index(Unit):ModelsCollectionとなるわけですね.
で,ArrayCollectionはDataGrid, AdvancedDataGrid, ListなどとのDataProviderとしては良いのですが,
TreeなどはXMLListCollectionをDataProviderで与えなければなりません.
ちなみに,XMLListCollectionは XMLListCollection < XMLList(複数のrootノードがあるXML) < XML
になります.

話がそれましたが,何が面倒かというと,
TreeにDataを渡すには,ArrayCollectionからXMLListやXMLListCollectionなど,Treeに適したDataに変換しなくてはなりません.
仕方がないので,変換する関数を書きました.
再起的にArrayを構成していきます.

private function onUnitSelect():void {
_unit = RxUtils.clone(unitsList.selectedItem.data) as Unit;
}


import org.restfulx.collections.ModelsCollection;
private function convertTree(units:ModelsCollection):Array{
var array:Array = new Array();
for each(var item:Unit in units){
if(item.parent==null){
array.push(getChild(item));
}
}
return array;
}

private function getChild(item:Unit):Object{
if(item.children==null){
return {label:item.name,data:item};
}else{
var children:Array = new Array();
for each(var c:Unit in item.children){
children.push(getChild(c));
}
return {label:item.name,data:item,children:children};
}
}

  • (中略)-



な感じです.
これで,事件は解決です.

RestfulX導入記 -その2 model編-

RestfulxのModelの解説を読んでいると結構凄いことが分かります.

今回は,下記の要約です.
http://wiki.github.com/dima/restfulx_framework/working-with-restfulx-models

上記記事では,何ができるかとどのように実現するのかを順に書いてあります.

  1. 普通のmodel
  2. has_many, has_one, belongs_toなどの基本的な関連
  3. ポリモーフィック関連
  4. 自己参照,ツリー構造(acts_as_treeも利用)
  5. has_many等のオプション関係,:class=>とか
  6. 単一テーブル継承
  7. 多対多のhas_many :through=>
  8. 条件付き関連(動的にhas_manyとかができるっぽい)
  9. ネストしたもの(has_oneとかの情報も同時に送る)
  10. 自分でrailsのmodelに追加したメソッド
  11. modelのprefix(Flexで参照するときに便利らしい)

ということらしいです.
これだけできれば十分です.

ありがとうございます.

RestfulX導入記 -その1おまけ-

その1でチュートリアルを終わらせたので,とりあえず落ち着いてディレクトリ構造とかを確認.

通常のRailsから追加されているのは以下.
public > index(ファイル内容が下記swfの読み込みになっている)
public > bin > Pomodo.swf(基本このファイルが読み込まれる)
app > flex(models,controllers,views,helpersとは別にディレクトリができている)


で,肝心のflexディレクトリはflexプロジェクトになっている.

で,pomodoの下が肝心なので,見てみる


となっています.
基本的に,Railsと似せて作ってあることが分かります.
controllersには,modelの一覧等の設定ファイル的なことが書かれています.

modelsの中には,railsのmodelと同じものがあり,publicな変数でカラムに対応した変数が定義されています.
また,単純な変数ではない,Date型やHasManyなどもここで定義します.

componentsの中には,各ページが入っており,アプリケーションファイルPomodo.mxmlで用いているようです.
なお,ここがcontroller的な役割も果たし,saveやdestroyなどのメソッドも書かれています.

長くなったのでいったんここで.