5

在过去的几天里,我一直在玩 Rails。

我不确定是否应该嵌套资源,以及如何确定它。

假设我有一个应用程序,用户可以在其中注册并制作待办事项列表。他们可以选择将这些列表设为公开或私有。

我遇到麻烦的地方是我是否应该将列表嵌套在用户资源下:

如果我这样做,我最终会得到类似的结果:

/users/:id/lists /users/:id/lists/:list_id

但是,如果我想说,查看下的所有公共列表/lists怎么办?那会干扰路线的宁静,不是吗?

我无法嵌套列表并为用户和列表设置单独的路由,但至少在我看来,我又遇到了麻烦。

/users/:id # some profile page /lists # should this link to all lists or all the current user's lists?

但是,如果我想显示特定用户的列表,我不知道我的路线是什么。

有没有办法以某种方式结合它?将列表嵌套在用户资源下,但仍然有/listslist_path?或者这只是一个自定义命名路线?

我对那些比我更精通 Rails 的人如何解决这个问题很感兴趣。

4

1 回答 1

1

您可以同时拥有嵌套列表和非嵌套列表。

resources :lists将创建所有宁静的路线。

resources :users do
  resources :lists
end

然后将创建所有嵌套路由和关联的助手。在这种情况下,我不会使用嵌套路由,因为您的控制器将是一个狗屎秀。

嵌套路由(比如说 users/7/lists)默认路由到ListsController#index,但你也有 /lists 去ListsController#index。因此,您可以向控制器添加一些逻辑:

ListsController < ApplicationController
  def index
    if params[:user_id].present?
      # I'm in a user_list
    else
      # I'm in a public list
    end
  end
end

啊。

好的 before_filter 怎么样?

ListsController < ApplicationController
  before_filter :unjankify_nested_routes

  private      

  def unjankify_nested_routes
    if params[:user_id].present?
      # I'm in a user_list
      render "users_#{@action}"
    else
      # I'm in a public list
    end
  end
end

现在我们基本上可以通过说 users_show、users_index 等来确定控制器方法的范围。但是那个 @action 变量是什么?我们需要捕捉到这一点。

class ApplicationController     
  def process_action(name, *args)
    @action_name = name
    super rescue false #no super in tests
  end
end

我们只是重写了一个内部 Rails 方法来捕获动作名称。这很有趣,但似乎我们做错了什么。

正确的方式(tm)

没有“正确的方法”,但范围是一个不错的选择

scope 'privates' do
  resources :lists
end

现在我们可以有一个Privates::ListsControllerin app/controllers/privates/lists_controller。您可以在查询参数中添加 user_id,或在范围内嵌套路由:

scope 'privates' do
  resources :users do  
    resources :lists
  end
end
于 2012-12-02T20:06:54.870 回答