Flex with Rails, just want to update a record....how hard can this be?
I have this in Flex:
<mx:HTTPService id="update"
url="http://localhost:3000/people/{grid.selectedItem.id}.xml?_method=put"
contentType="application/xml"
resultFormat="e4x"
method="POST"
result="index.send()"/>
And when it fires I get the following error in Rails:
Processing ApplicationController#index (for 127.0.0.1 at 2009-12-开发者_StackOverflow中文版07 05:33:55) [POST]
Parameters: {"person"=>{"first_name"=>"Paul", "last_name"=>"Goulart"}}
ActionController::MethodNotAllowed (Only get, put, and delete requests are allowed.):
-e:2:in `load'
-e:2
If I edit the same record using scaffolding provided by rails it works:
Processing PeopleController#update (for 127.0.0.1 at 2009-12-07 05:37:08) [PUT]
Parameters: {"commit"=>"Update", "authenticity_token"=>"MV9lFxBGxPgqP0WRTqEWa9/8D36ZzX9opk0SzJ3hUjA=", "id"=>"2", "person"=>{"first_name"=>"Paul", "address"=>"San Francisco", "last_name"=>"Goulart"}}
[4;35;1mPerson Columns (8.0ms)[0m [0mSHOW FIELDS FROM `people`[0m
[4;36;1mPerson Load (0.0ms)[0m [0;1mSELECT * FROM `people` WHERE (`people`.`id` = 2) [0m
[4;35;1mSQL (0.0ms)[0m [0mBEGIN[0m
[4;36;1mPerson Update (0.0ms)[0m [0;1mUPDATE `people` SET `first_name` = 'Paul', `updated_at` = '2009-12-07 13:37:08' WHERE `id` = 2[0m
[4;35;1mSQL (1.0ms)[0m [0mCOMMIT[0m
This should be an easy thing. Just trying to update data from flex using xml.
I'm stuck. Can anyone help?
Thanks.
Paul
I think you need to post _method parameter. It isn't accepting the _GET for the method parameter, and returning that only GET, PUT, and DELETE requests are allowed for this route.
Only get, put, and delete requests are allowed.
change method="POST"
to method="PUT"
or method="GET"
<mx:HTTPService id="update"
url="http://localhost:3000/people/{grid.selectedItem.id}.xml?_method=put"
contentType="application/xml"
resultFormat="e4x"
method="GET"
result="index.send()"/>
HTTPService
supports GET
, POST
, HEAD
, OPTIONS
, PUT
, TRACE
and DELETE
methods.
Ok, finally figured out how to do a RESTful CRUD in Flex with Ruby on Rails. Thanks everybody who responded. I've been studying the Flex on Rails book by Tony Hillerson and Daniel Wanja. Somehow I couldn't get it to work. The delete wasn't working because in their example they had a delete and my method was called destroy. Anyways, it's a good book and I thought I'd share how I got to the solution that works. Turns out it was just adding in the update or destroy convention in the HTTPService tags.
Create the scaffolding for Account
script/generate scaffold Account name:string (You may have to do a db:create or db:migrate)
The Accounts Controller looks like this:
class AccountsController < ApplicationController def index @accounts = Account.find(:all) render :xml => @accounts end
def create @account = Account.new(params[:account]) if @account.save render :xml => @account, :status => :created, :location => @account else render :xml => @account.errors, :status => :unprocessable_entity end end
def update @account = Account.find(params[:id]) if @account.update_attributes(params[:account]) head :ok else render :xml => @account.errors, :status => :unprocessable_entity end end
# DELETE /accounts/1 # DELETE /accounts/1.xml def destroy @account = Account.find(params[:id]) @account.destroy head :ok end end
Routes.rb looks like this:
ActionController::Routing::Routes.draw do |map| map.resources :accounts map.connect 'accounts/:id', :controller => 'accounts', :action => 'update' # The priority is based upon order of creation: first created -> highest priority.
# Sample of regular route: # map.connect 'products/:id', :controller => 'catalog', :action => 'view' # Keep in mind you can assign values other than :controller and :action
# Sample of named route: # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase' # This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically): # map.resources :products
# Sample resource route with options: # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
# Sample resource route with sub-resources: # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
# Sample resource route with more complex sub-resources # map.resources :products do |products| # products.resources :comments # products.resources :sales, :collection => { :recent => :get } # end
# Sample resource route within a namespace: # map.namespace :admin do |admin| # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb) # admin.resources :products # end
# You can have the root of your site routed with map.root -- just remember to delete public/index.html. # map.root :controller => "welcome"
# See how all your routes lay out with "rake routes"
# Install the default routes as the lowest priority. # Note: These default routes make all actions in every controller accessible via GET requests. You should # consider removing or commenting them out if you're using named routes and resources. map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end
The mxml file looks like this:
private const CONTEXT_URL:String = "http://localhost:3000";
private function addNewAccount():void {
accounts.appendChild(<account><id></id><name>new name</name></account>);
}
]]>
</mx:Script>
<mx:HTTPService id="accountsIndex" url="{CONTEXT_URL}/accounts"
resultFormat="e4x"
result="accounts=event.result as XML" />
<mx:HTTPService id="accountsCreate" url="{CONTEXT_URL}/accounts"
method="POST" resultFormat="e4x" contentType="application/xml"
result="accountsIndex.send()" />
<mx:HTTPService id="accountsUpdate"
url="{CONTEXT_URL}/accounts/{accountsGrid.selectedItem.id}?_method=put"
method="POST" resultFormat="e4x" contentType="application/xml" />
<mx:HTTPService id="accountsDelete"
url="{CONTEXT_URL}/accounts/destroy/{accountsGrid.selectedItem.id}"
method="POST" resultFormat="e4x" contentType="application/xml"
result="accountsIndex.send()" >
<mx:request>
<_method>
destroy
</_method>
</mx:request>
</mx:HTTPService>
<mx:DataGrid id="accountsGrid"
dataProvider="{accounts.account}"
editable="true">
<mx:columns>
<mx:DataGridColumn headerText="Id" dataField="id" editable="false"/>
<mx:DataGridColumn headerText="Name" dataField="name" />
</mx:columns>
</mx:DataGrid>
<mx:Button label="New"
click="addNewAccount()"
enabled="{accountsGrid.dataProvider!=null}" />
<mx:Button label="{accountsGrid.selectedItem.id==''?'Create':'Update'}"
click="accountsGrid.selectedItem.id=='' ?
accountsCreate.send(accountsGrid.selectedItem) :
accountsUpdate.send(accountsGrid.selectedItem)" />
<mx:Button label="Delete"
click="accountsGrid.selectedItem.id=='' ?
accountsIndex.send() : accountsDelete.send()"
enabled="{accountsGrid.selectedItem!=null}" />
精彩评论