我们正在探索一种在 Rails 中处理质量分配保护的新方法。实际上,这并不是一种全新的方法,它更像是一种将既定实践提炼出来,并加入一些“醋”以应对你可能忘记的情况。这种新方法将成为 Rails 4.0 的默认功能,但我们希望在正式发布之前得到您的帮助来测试和完善它。
这种新方法是 slice 模式 的提炼,我们称之为 strong_parameters 插件(也已 作为 gem 提供)。基本思想是将质量分配保护从模型移到控制器,而它本就属于那里。
控制器的整个目的是控制用户和应用程序之间的流程,包括身份验证、授权以及作为其中的一部分的访问控制。我们本不应该将质量分配保护放入模型中,而且很多人早已停止这样做,转而采用 slice 模式或其变体。现在是时候将这种模式提炼出来并推广给大家了。
class PeopleController < ActionController::Base
# This will raise an ActiveModel::ForbiddenAttributes exception because it's using mass assignment
# without an explicit permit step.
def create
Person.create(params[:person])
end
# This will pass with flying colors as long as there's a person key in the parameters, otherwise
# it'll raise a ActionController::MissingParameter exception, which will get caught by
# ActionController::Base and turned into that 400 Bad Request reply.
def update
redirect_to current_account.people.find(params[:id]).tap do |person|
person.update_attributes!(person_params)
end
end
private
# Using a private method to encapsulate the permissible parameters is just a good pattern
# since you'll be able to reuse the same permit list between create and update. Also, you
# can specialize this method with per-user checking of permissible attributes.
def person_params
params.required(:person).permit(:name, :age)
end
end
我们仍在调整 API,但它已经足够好用了。我已经用 strong_parameters 的 permit 方法替换了我们在新版 Basecamp 中使用的 slice 模式。
我们仍在努力寻找一种整洁的方式来处理嵌套参数,但已经有一个设计准备好实现,所以应该不会太远。此外,Yehuda 将致力于表单签名,这将减轻在标准 HTML 表单情况下手动声明允许参数的需要(您仍然需要手动允许参数以用于 API 和其他客户端)。
但现在它已经足够有用了。该插件目前仅完全兼容 rails/3-2-stable rev 275ee0dc7b 及更高版本,以及 rails/master rev b49a7ddce1 及更高版本,原因是存在一个关于包装参数的测试问题(如果您不为 JSON API 使用包装参数,则可以使用该插件与任何版本的 Rails 3.2 兼容)。