Rails 3:两个单一的嵌套资源,一个模型

时间:2022-01-15 12:13:19

I'm working on my first bigger project in Rails. It will be a RESTful API. The situation I've stumbled upon can be described as the following: I have the models 'Person' and 'Application'.

我正在研究我在Rails中的第一个更大的项目。它将是一个RESTful API。我偶然发现的情况可以描述如下:我有模型'Person'和'Application'。

class Person < ActiveRecord::Base
  has_many :managed_applications, :class_name => "Application", :foreign_key => "manager_id"
  has_many :owned_applications, :class_name => "Application", :foreign_key => "owner_id"

  # other associations
  has_many :adresses
end

class Application < ActiveRecord::Base
  belongs_to :manager, :class_name => "Person"
  belongs_to :owner, :class_name => "Person"
end

How should I design my controllers and routes, so that I have the following quite self-explanatory resources working?

我应该如何设计我的控制器和路由,以便我有以下相当不言自明的资源工作?

/applications/<id>/owner
/applications/<id>/manager
/people/<id>

The problem is, that when is nest singular owner and manager resources under a "plural" applications resource, all routes end up in the identical 'PeopleController' actions, with the same params.

问题是,当在“复数”应用程序资源下嵌套单个所有者和管理器资源时,所有路由都以相同的“PeopleController”操作结束,具有相同的参数。

A bonus would be, if the first two resources would act as the last one in terms of read-only operations (e.g., you could retrieve the addresses of the manager of a specific application just with one request, 'GET /applications/<id>/owner/adresses'). Is that even recommended API design?

如果前两个资源在只读操作方面将作为最后一个资源(例如,您可以仅使用一个请求检索特定应用程序的管理器的地址,那么'GET / applications / /所有者/不会忽略)。这甚至是推荐的API设计吗?

Thanks a lot.

非常感谢。

1 个解决方案

#1


1  

I think it is indeed a valid REST approach but I would remove the deep nesting of addresses one level up. Then people will be a shallow resource of its own and thus have its own addresses. I do this because REST nesting of level more than 1 is dicouraged. See http://guides.rubyonrails.org/routing.html Now let's address the other problem. How will the controller know that the user requested 'owner' or 'manager'. One way is to use default params right in routes like this :

我认为这确实是一种有效的REST方法,但我会删除一级地址的深层嵌套。然后人们将成为自己的浅层资源,因此拥有自己的地址。我这样做是因为不建议使用超过1级的REST嵌套。请参阅http://guides.rubyonrails.org/routing.html现在让我们解决另一个问题。控制器如何知道用户请求“所有者”或“经理”。一种方法是在这样的路线中使用默认参数:

resources :applications do
  resource :owner, :controller => 'people', :defaults => {:type => 'owner'}
  resource :manager, :controller => 'people', :defaults => {:type => 'manager'}
end

resources :people do
  resources :address
end

Then in your PeopleController:

然后在你的PeopleController中:

class PeopleController < ApplicationController
  def show
    @type = params[:type] # can be manager, owner or nil
  end
end

But beware that here the user can override these default params in the url so I'm leaving the security implications to you.

但请注意,用户可以在URL中覆盖这些默认参数,这样我就会对您产生安全隐患。

The other way is to check request.fullpath which yields the full url address. In it you can search for either manager or owner.

另一种方法是检查request.fullpath,它产生完整的url地址。在其中,您可以搜索经理或所有者。

Good luck!

祝你好运!

#1


1  

I think it is indeed a valid REST approach but I would remove the deep nesting of addresses one level up. Then people will be a shallow resource of its own and thus have its own addresses. I do this because REST nesting of level more than 1 is dicouraged. See http://guides.rubyonrails.org/routing.html Now let's address the other problem. How will the controller know that the user requested 'owner' or 'manager'. One way is to use default params right in routes like this :

我认为这确实是一种有效的REST方法,但我会删除一级地址的深层嵌套。然后人们将成为自己的浅层资源,因此拥有自己的地址。我这样做是因为不建议使用超过1级的REST嵌套。请参阅http://guides.rubyonrails.org/routing.html现在让我们解决另一个问题。控制器如何知道用户请求“所有者”或“经理”。一种方法是在这样的路线中使用默认参数:

resources :applications do
  resource :owner, :controller => 'people', :defaults => {:type => 'owner'}
  resource :manager, :controller => 'people', :defaults => {:type => 'manager'}
end

resources :people do
  resources :address
end

Then in your PeopleController:

然后在你的PeopleController中:

class PeopleController < ApplicationController
  def show
    @type = params[:type] # can be manager, owner or nil
  end
end

But beware that here the user can override these default params in the url so I'm leaving the security implications to you.

但请注意,用户可以在URL中覆盖这些默认参数,这样我就会对您产生安全隐患。

The other way is to check request.fullpath which yields the full url address. In it you can search for either manager or owner.

另一种方法是检查request.fullpath,它产生完整的url地址。在其中,您可以搜索经理或所有者。

Good luck!

祝你好运!