我目前正致力于构建在Rails 3上的Web应用程序,该应用程序大量使用Ajax / REST作为客户端。因此,我经常发现自己编写这样的控制器动作:
def create
if !params[:name]
respond_to do |format|
format.html { render json: {}, status: :not_found }
format.json { render json: {}, status: :not_found }
end
return
end
account = ...
respond_to do |format|
format.html { render json: account }
format.json { render json: account }
end
end
几乎所有的操作都在成功案例或错误代码中返回json对象。但是,如果我想让操作更早返回,我总是必须编写这个详细的respond_to块和一个返回。
相反,我想使用类似的东西,或类似的替代方案:
def create
if !params[:name]
throw :not_found
end
account = ...
return account
end
如何使用Rails 3+完成这项工作?
答案 0 :(得分:2)
查看inherited_resources。这将允许您将控制器重写为:
class SomeController < ApplicationController
inherit_resources
respond_to :html, :js, :json
end
就是这样。您可以像往常一样访问所有创建/读取/更新/删除方法。您可以像过去一样继承自使用inherited_resources的主资源控制器,然后您可以更通用的方式调整响应。
class ResourcesController < ApplicationController
inherit_resources
respond_to :html, :js
def create
create! do |format|
format.js do
# generic code here for managing all create methods initiated via js
# current model is avialbe via 'resource'
# e.g 'resource.errors'
end
end
end
然后继承该控制器:
class SomeController < ResourcesController
end
这种抽象在大多数情况下都可能过度,但在处理30或40个需要类似控制器的模型时它非常方便。
Inherited_resources提供了许多帮助程序来访问当前模型(称为资源)以便于动态引用,因此您可以根据资源/模型名称返回相关表单或部分。
为了让您了解如何使用它,您可以使用参数中的控制器名称返回当前控制器的表单。需要注意的是,格式错误的控制器名称将无法访问此方法(因为它将返回404),因此可以安全使用:
format.js do
render "#{params[:controller]}/form"
end
最重要的是,您可以通过在特定控制器中定义任何方法来覆盖任何方法。
答案 1 :(得分:1)
如果你总是返回json,你可以省略respond_to
块并将它写成:
def create
if !params[:name]
render json: {}, status: :not_found
return
end
account = ...
render json: account
end