如何在rails路由助手中覆盖方法(PUT vs GET)?

时间:2013-01-24 23:48:18

标签: ruby-on-rails nested-resources

所以我遇到了带有作用域路由和form_for:form_for and scopes, rails 3

的问题

我的问题更糟糕,因为我不只是想要扩展所有方法的范围,我希望所有方法都在'/ admin'之外,除了GET / show。

所以我的routes.rb有这样的东西:

scope '/admin' do
  resources 'lessons', except: [:show]
end
get "lessons/:id" => "lessons#show", :as => "lesson"

运行rake路线实际上显示了我想要的内容,其中两个版本的lesson_path只有方法,PUT和GET不同。所以其他解决方案提供了这样的地方:

url = @lesson.persisted? ? lesson_path(@lesson) :  lessons_path
form_for @lesson, url: url do

对我不起作用,因为lesson_path(@lesson)将始终返回没有/ admin前缀的GET路径,该路径仍然会破坏我的表单。

所以我无法弄清楚的是,我可以在rails路径帮助器中指定方法,以便它将使用以/ admin开头的路由吗?或者是否有完全不同的方式来实现这个目标?我知道我可以通过更改来解决问题:

get "lessons/:id" => "lessons#show", :as => "lesson"

get "lessons/:id" => "lessons#show", :as => "show_lesson"

但是在这一点上我只是想知道它是否可能,如果是这样,那么“正确”的方式是什么。

1 个答案:

答案 0 :(得分:0)

我认为你正在寻找这种语法:

<%= form_for [:admin, @lesson] do |f| %>
  # form goes here
<% end %>

如果admin_lesson_path@lesson,这将构建一个名为persisted?的多态路由助手,如果不是,则构建admin_lessons_pathadmin_lesson_path帮助器将传递@lesson对象,因此路径类似于admin/lessons/1admin_lessons_path会生成/admin/lessons。然后,表单将知道是否使用POSTPUT,具体取决于记录是否保留。

您可以在路径文件中定义路由帮助,如下所示:

 namespace :admin do
   resources :lessons
 end

通过命名空间控制器,它有几个优点。其中之一是您可以将所有管理员的东西放在一个命名空间后面,然后从该命名空间继承基本控制器:

 module Admin
   class LessonsController < BaseController 

   end
 end

然后BaseController将包含用于限制用户是否可以在该控制器中执行操作的逻辑(作为before_filter)。

通过将所有管理员资料放入这些命名空间控制器中,您可以将所有管理操作保留在一个位置,并将所有面向用户的操作保存在另一个位置。如果你听说过“关注点分离”,那么这是一个很好的例子。