... mostly about Ruby and Rails...

Donnerstag, 30. August 2007

Quickie: find a route with ./script/console

... so I was playing around with hobo and wanted to add another method to a controller. The controller was made by hobo scaffolding and looked like that one:


class InstancesController < ApplicationController
hobo_model_controller
end


In hobo, you add another method by calling it a 'web_method':


class InstancesController < ApplicationController
hobo_model_controller
web_method :chart

def chart
end
end


According to the documentation, this should be all, but when I tried to use it:


$ curl -v http://localhost:3000/instances/1/chart
> GET /instances/1/chart HTTP/1.1
> Host: localhost:3000
> Accept: */*
>
< HTTP/1.1 404 Not Found


and the server says:

Processing InstancesController#1 (for 127.0.0.1 at 2007-08-30 17:12:51) [GET]
Session ID: da18a6b4ef8b5d17773f4f4b3c117895
Parameters: {"action"=>"1", "id"=>"chart", "controller"=>"instances"}

Rendering /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/templates/rescues/layout.rhtml (404 Page Not Found)


wait a second... "action"=>"1", "id"=>"chart"... this should be the other way around! Hobo did not seem to have added the correct route. Let's have a look at that with the rails console:


$ ./script/console
Loading development environment.
>> # List all routes
?> ActionController::Routing::Routes.named_routes.routes.each do |name, route|
?> puts "%20s: %s" % [name, route] if name.to_s.include? "chart"
>> end; nil
instance_chart: POST /instances/:id/chart/ {:action=> "chart", :controller=>"instances"}
=> nil
>>


Okay, here is the problem. The route is only added for POSTing it, not GETting :( So, let's use curl with a POST:


$ curl -v -d "some_data" http://localhost:3000/instances/1/chart
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST /instances/1/chart HTTP/1.1
> Host: localhost:3000
>
< HTTP/1.1 403 Forbidden
< Connection: close
< Date: Thu, 30 Aug 2007 15:26:59 GMT
< Set-Cookie: _supervisor_session_id=ee7182c092c5222820bf458316c19deb; path=/
< Status: 403 Forbidden
< Pragma: no-cache
< Cache-Control: no-store
< Server: Mongrel 1.0.1
< Content-Type: text/html; charset=utf-8
< Content-Length: 17
< Expires: 0
<
* Closing connection #0


Aha, a change. So, that's how hobo wants to do it. But I need to use GET. So, config/routes.rb needs an additinal route:


map.named_route("instance_chart_get",
"instances/:id/chart",
:controller => 'instances',
:action => 'chart',
:conditions => { :method => :get } )


And now, what does curl, now:


$ curl -v http://localhost:3000/instances/1/chart
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST /instances/1/chart HTTP/1.1
> Host: localhost:3000
>
< HTTP/1.1 403 Forbidden
< Connection: close
< Date: Thu, 30 Aug 2007 15:26:59 GMT
< Set-Cookie: _supervisor_session_id=ee7182c092c5222820bf458316c19deb; path=/
< Status: 403 Forbidden
< Pragma: no-cache
< Cache-Control: no-store
< Server: Mongrel 1.0.1
< Content-Type: text/html; charset=utf-8
< Content-Length: 17
< Expires: 0
<
* Closing connection #0


and in the console:


$ ./script/console
Loading development environment.
>> ActionController::Routing::Routes.named_routes.routes.each do |name, route|
?> puts "%20s: %s" % [name, route] if name.to_s.include? "chart"
>> end; nil
instance_chart: POST /instances/:id/chart/ {:action=>"chart", :controller=>"instances"}
instance_chart_get: GET /instances/:id/chart/ {:action=>"chart", :controller=>"instances"}
=> nil
>>


Fine for me!!