RailsActionController::Parameters 是一种将数据从请求传递到控制器动作的便捷方式。每一个带参数的请求到控制器动作,都应该被极其谨慎地处理。ActionController::Parameters 是一种便捷的方式。
在Rails 7中,我们现在可以使用.to_h 方法将ActionController::Parameters 对象转换为标准的Hash。这对于想要定制数据传递给控制器的方式的开发者来说是个好消息。 这也意味着我们可以改变参数的行为,而不必在客户端代码上做任何改变。
让我们假设我们已经为一个产品模型搭建了脚手架,将product_name,product_price, 和product_image 作为属性。
class ProductsController < ApplicationController
def create
@product = Product.new(product_params)
respond_to do |format|
# respond to HTML, JSON
end
end
private
# Only allow a list of trusted parameters through.
def product_params
params.require(:product).permit(:product_name, :product_price, :product_image)
end
end
现在,如果前端应用程序发送了一个带有适当参数的适当请求,我们应该能够创建一个新的产品。
{
"product": {
"product_name": "Ruby Programming 101",
"product_price": "15.00"
"product_image": "http://link-to-image-url/image.jpg"
}
}
但是,如果客户端的请求体有不同的键/值对呢?
{
"product": {
"name": "Ruby Programming 101",
"price": "15.00"
"image": "http://link-to-image-url/image.jpg"
}
}
之前
在Rails 7之前,解决这个问题的方法是改变强大的params键,然后在控制器内一个一个地修改键。
class ProductsController < ApplicationController
def create
params = product_params
@product = Product.new
@product.product_name = params[:product][:name]
@product.product_price = params[:product][:price]
@product.product_image = params[:product][:image]
respond_to do |format|
# respond to HTML, JSON
end
end
private
# Only allow a list of trusted parameters through.
def product_params
params.require(:product).permit(:name, :price, :image)
end
end
在这种情况下,需要大量的手动更新,这感觉并不是一个好的做法。
之后
相反,在Rails 7中,我们可以在参数对象上使用to_h 方法,将其转换为标准的Hash,然后在控制器中对键进行修改。 这使得我们可以更智能地处理参数,而不需要大量的手动更新。 to_h 方法根本没有改变参数对象的行为,所以不需要以任何方式修改它。
class ProductsController < ApplicationController
def create
@product = Product.new(product_params)
respond_to do |format|
# respond to HTML, JSON
end
end
private
# Only allow a list of trusted parameters through.
def product_params
params.require(:product)
.permit(:name, :price, :image)
.to_h { |key, value| [:"product_#{key}", value] }
end
end
这个解决方案看起来和感觉都很像Rails的方式。 干净的代码,简单易懂的逻辑!
上面的例子只是使用ActionController::Parameters的.to_h 方法的一种方式,我们还可以修改params hash的值来。
params = ActionController::Parameters.new(language: "Ruby", framework: "Ruby on Rails", version: "7.0.1")
params.to_h { |key, value| [key, "#{value == "Ruby" ? "Best Programming language on Earth" : value}"] }
=> {"language"=>"Best Programming language on Earth", "framework"=>"Ruby on Rails", "version"=>"7.0.1"}