过去几天我一直在玩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?
但是,如果我想显示特定用户的列表,我不知道我的路线是什么。
有没有办法以某种方式结合这个?将列表嵌套在用户资源下,但仍然有/lists
lists_path?或者这只是一个自定义的命名路线?
我对Rails中比我更熟练的人会如何解决这个问题感兴趣。
答案 0 :(得分:1)
您可以同时拥有嵌套列表和非嵌套列表。
resources :lists
将创建所有其余的路线。
resources :users do
resources :lists
end
然后将创建所有嵌套路由和关联的帮助程序。我不会在这种情况下使用嵌套路由,因为你的控制器将是一个shitshow。
嵌套路由(假设用户/ 7 /列表)默认路由到ListsController#index
,但您也有/列表将转到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方法来捕获操作名称。这很有趣,但有点似乎我们做错了。
没有“正确的方法”,但scopes是一个不错的选择
scope 'privates' do
resources :lists
end
现在我们可以在Privates::ListsController
中拥有app/controllers/privates/lists_controller
。您可以在查询参数中添加user_id,或在范围下嵌套路由:
scope 'privates' do
resources :users do
resources :lists
end
end