Forum: Ruby on Rails How to consume a nested singular resource?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Matthew F. (Guest)
on 2008-10-09 16:08
Hi,

We have a RESTful server application which exposes the following routes
using the following rules, but when trying to consume those resources
from a client application the routes are not generated correctly. And we
are not sure how to get around that.

The routes.rb specifies the following resources:

ActionController::Routing::Routes.draw do |map|
  map.resources :users do |user|
    user.resource :blog
  end

  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end

Generated routes (only a subset):

POST   /users/:user_id/blog                 {:controller=>"blogs",
:action=>"create"}
POST   /users/:user_id/blog.:format         {:controller=>"blogs",
:action=>"create"}
new_user_blog GET    /users/:user_id/blog/new
{:controller=>"blogs", :action=>"new"}
formatted_new_user_blog GET    /users/:user_id/blog/new.:format
{:controller=>"blogs", :action=>"new"}
edit_user_blog GET    /users/:user_id/blog/edit
{:controller=>"blogs", :action=>"edit"}
formatted_edit_user_blog GET    /users/:user_id/blog/edit.:format
{:controller=>"blogs", :action=>"edit"}
user_blog GET    /users/:user_id/blog
{:controller=>"blogs", :action=>"show"}
formatted_user_blog GET    /users/:user_id/blog.:format
{:controller=>"blogs", :action=>"show"}
PUT    /users/:user_id/blog                 {:controller=>"blogs",
:action=>"update"}
PUT    /users/:user_id/blog.:format         {:controller=>"blogs",
:action=>"update"}
DELETE /users/:user_id/blog                 {:controller=>"blogs",
:action=>"destroy"}
DELETE /users/:user_id/blog.:format         {:controller=>"blogs",
:action=>"destroy"}

The routes are exactly as we would like them. i.e. per user there is
only one blog.

The problem starts when trying to consume these resources using active
resource from a client application (ie another rails app to consume the
REST api resources). Here is a description of the models:

class User < ActiveResource::Base
  self.site = "http://localhost:3000/"
end

class Blog < ActiveResource::Base
  self.site = "http://localhost:3001/users/:user_id/"
end

CRUD operations for the User model work fine. No problem there. But on
inspection of the collection and element paths for the Blog model the
following urls are generated:

Blog.collection_path(:user_id => 1)
=> "/users/1/blogs.xml"

Blog.element_path(1, :user_id => 1)
=> "/users/1/blogs/1.xml"

On trying to create a blog for a specific user:

b = Blog.new(:params => {:user_id => 1})
>> b.save
ActiveResource::ResourceNotFound: Failed with 404 Not Found

the client application gets a 404 because the generated url is incorrect
and the REST API application throws an ActionController::UnknownAction
exception because the generated route is routed to the wrong controller
and action, in this case:

/users/1/blogs.xml

gets routed to the users controller and tries to execute the 1 action.
So, this cannot work, since the REST api cannot resolve these urls to
routes since we have specified a singular resource i.e. "blog".

Can anyone help us with specifying how the consuming active resource
models generate the correct urls for a singular nested resource? As we
don't want to change the api specification as it is proper and concise.

Thanks in advance for your time.
This topic is locked and can not be replied to.