组织 Rails 控制器索引的最佳方式
Best way to organize Rails controller index
我们的应用程序可以跟踪未经预约就走进我们诊所的客户。我们从一个简单的 WalkIn 模型和 WalkInsController 开始。
然后我们添加了另一种类型的步入式,然后是另一种......所以现在我们的#index 动作必须在四种不同的步入式类型之间进行过滤,有时会以不同的方式对待它们。
其他 REST 操作(#show 除外)在类型之间大部分相同,但可能有一些细微差别。我们还有一些非 REST 方法,它们并不适合其他任何地方。
因此,至少需要驯服这个#index 动作。
第一个想法:我将命名空间 walk_ins 仅用于 #index:
namespace :walk_ins do
get 'clinic' => 'clinic_walk_ins#index', :as => :clinic
get 'group' => 'group_walk_ins#index', :as => :group
get 'assessment' => 'assessment_walk_ins#index', :as => :assessment
get 'initial' => 'initial_walk_ins#index', :as => :initial
end
resources :walk_ins, except: [ :index ] do
member do
get :eligible_initial_appointments
patch :mark_follow_up_as_completed
end
collection do
get :follow_up_due
end
end
因此,我将为初始步入式的#index 操作创建 WalkIns::InitialWalkInsController
等,我将为其余资源保留顶级 WalkInsController
。
但是由于命名空间与顶层控制器相同——walk-ins
——我不能做walk_ins/initial
,因为Rails会把它当作walk_ins#show
并说找不到 ID 为“show”的 WalkIn。
我可以简单地更改命名空间的名称,但 walk_ins
确实最有意义。
第二遍 -- 将所有资源路由嵌入命名空间:
namespace :walk_ins do
get 'clinic' => 'clinic_walk_ins#index', :as => :clinic
get 'group' => 'group_walk_ins#index', :as => :group
get 'assessment' => 'assessment_walk_ins#index', :as => :assessment
get 'initial' => 'initial_walk_ins#index', :as => :initial
resources :walk_ins, except: [ :index ] do
member do
get :eligible_initial_appointments
patch :mark_follow_up_as_completed
end
collection do
get :follow_up_due
end
end
end
这很有效,并且为每种类型的 walk_in#index.
配备一个独立的控制器真是太棒了
但现在每个非索引的资源都必须在 walk_ins/walk_ins
.
中
例如,要编辑 WalkIn 3,URL 是:
/walk_ins/walk_ins/3/edit
这好像...不是我想要的。
最好的组织方式是什么?
您可以像这样在收集块中移动所有 walk_ins 过滤器
resources :walk_ins, except: [ :index ] do
member do
get :eligible_initial_appointments
patch :mark_follow_up_as_completed
end
collection do
get :follow_up_due
get 'clinic', controller: 'walk_ins/clinic_walk_ins', action: 'index', as: 'clinic'
get 'group', controller: 'walk_ins/group_walk_ins', action: 'index', as: 'group'
get 'assessment', controller: 'walk_ins/assessment_walk_ins', action: 'index', as: 'assessment'
get 'initial', controller: 'walk_ins/initial_walk_ins', action: 'index', as: 'initial'
end
end
我们的应用程序可以跟踪未经预约就走进我们诊所的客户。我们从一个简单的 WalkIn 模型和 WalkInsController 开始。
然后我们添加了另一种类型的步入式,然后是另一种......所以现在我们的#index 动作必须在四种不同的步入式类型之间进行过滤,有时会以不同的方式对待它们。
其他 REST 操作(#show 除外)在类型之间大部分相同,但可能有一些细微差别。我们还有一些非 REST 方法,它们并不适合其他任何地方。
因此,至少需要驯服这个#index 动作。
第一个想法:我将命名空间 walk_ins 仅用于 #index:
namespace :walk_ins do
get 'clinic' => 'clinic_walk_ins#index', :as => :clinic
get 'group' => 'group_walk_ins#index', :as => :group
get 'assessment' => 'assessment_walk_ins#index', :as => :assessment
get 'initial' => 'initial_walk_ins#index', :as => :initial
end
resources :walk_ins, except: [ :index ] do
member do
get :eligible_initial_appointments
patch :mark_follow_up_as_completed
end
collection do
get :follow_up_due
end
end
因此,我将为初始步入式的#index 操作创建 WalkIns::InitialWalkInsController
等,我将为其余资源保留顶级 WalkInsController
。
但是由于命名空间与顶层控制器相同——walk-ins
——我不能做walk_ins/initial
,因为Rails会把它当作walk_ins#show
并说找不到 ID 为“show”的 WalkIn。
我可以简单地更改命名空间的名称,但 walk_ins
确实最有意义。
第二遍 -- 将所有资源路由嵌入命名空间:
namespace :walk_ins do
get 'clinic' => 'clinic_walk_ins#index', :as => :clinic
get 'group' => 'group_walk_ins#index', :as => :group
get 'assessment' => 'assessment_walk_ins#index', :as => :assessment
get 'initial' => 'initial_walk_ins#index', :as => :initial
resources :walk_ins, except: [ :index ] do
member do
get :eligible_initial_appointments
patch :mark_follow_up_as_completed
end
collection do
get :follow_up_due
end
end
end
这很有效,并且为每种类型的 walk_in#index.
配备一个独立的控制器真是太棒了但现在每个非索引的资源都必须在 walk_ins/walk_ins
.
例如,要编辑 WalkIn 3,URL 是:
/walk_ins/walk_ins/3/edit
这好像...不是我想要的。
最好的组织方式是什么?
您可以像这样在收集块中移动所有 walk_ins 过滤器
resources :walk_ins, except: [ :index ] do
member do
get :eligible_initial_appointments
patch :mark_follow_up_as_completed
end
collection do
get :follow_up_due
get 'clinic', controller: 'walk_ins/clinic_walk_ins', action: 'index', as: 'clinic'
get 'group', controller: 'walk_ins/group_walk_ins', action: 'index', as: 'group'
get 'assessment', controller: 'walk_ins/assessment_walk_ins', action: 'index', as: 'assessment'
get 'initial', controller: 'walk_ins/initial_walk_ins', action: 'index', as: 'initial'
end
end