如何同时上传多张图片和更新一个实体。 Rails API 和 JS 前端
How to upload multiple images and update an entity at the same time. Rails API and JS frontend
我正在尝试使用来自 React 前端的 formData 进行一次 API 调用,该前端具有多个图像加上 strings/booleans 等以更新实体
我正在使用活动存储并且我能够将多个图像附加到实体但是当我想用字符串等更新实体时通过一个 API 调用(理想情况下)。它是这样说的:
param is missing or the value is empty: property
我知道原因是我的formData结构是这样的:
data: {"title": "xxxxxx", "description": "xxxxxx" etc.}, images[]: File, images[]: File etc.
而且我需要 属性 作为键而不是数据:
def property_params
params.require(:property).permit(:title, :description, :max_guests, :price_per_day, :address,:average_rating, :has_beach_nearby, :has_beds, :has_kitchen, :has_swimming_pool, :has_hdtv,:has_bathtub, :images [])
end
但是当我不这样做时,图像无法识别,因为它是不允许的,所以 API 没有收到它
我正在附加这样的图像(并且有效):
if params[:images].present?
params[:images].each do |image|
@property.images.attach(image)
end
end
是否可以使用一次 API 调用上传多张图片和数据?如果没有,我需要做什么?
这是整个 属性 控制器:
class Api::V1::PropertiesController < ApiController
before_action :authenticate_user!, only: [:update, :create, :destroy]
def index
@properties = Property.all
render json: @properties
end
def show
@property = Property.find(params[:id])
render json: @property
end
def update
@property = Property.find(params[:id])
if current_user === @property.user
if params[:images].present?
params[:images].each do |image|
@property.images.attach(image)
end
end
@property.update(property_params)
render json: {
success: "Successfully updated",property: @property},
status: 200
else
render json: {
error: "You are not authorized to update this property"},
status: 403
end
end
private
def property_params
params.require(:property).permit(:title, :description, :max_guests, :price_per_day, :address,:average_rating, :has_beach_nearby, :has_beds, :has_kitchen, :has_swimming_pool, :has_hdtv,:has_bathtub, :images [])
end
被卡住了一段时间,非常感谢任何帮助(Rails 的新手)
Rack 使用括号在表单数据中传递哈希:
irb(main):005:0> Rack::Utils.parse_nested_query("property[title]=foo&property[description]=bar")
=> {"property"=>{"title"=>"foo", "description"=>"bar"}}
可以使用空括号传递数组:
irb(main):008:0> Rack::Utils.parse_nested_query("property[foo][]=a&property[foo]&[]=property[foo][]=c")
=> {"property"=>{"foo"=>nil}}
对于多部分表单数据,您通常会使用表单(可见表单或虚拟表单)并在输入上设置名称属性:
<form action="/properties" method="post" multipart>
<input name="property[images][]" type="file" />
<input name="property[images][]" type="file" />
</form>
Rack 会将请求正文的各个部分拼接在一起并创建单个参数哈希。
你也有语法错误:
# Use sensible line lengths and this won't happen as often...
params.require(:property)
.permit(
:title, :description, :max_guests,
:price_per_day, :address, :average_rating,
:has_beach_nearby, :has_beds, :has_kitchen,
:has_swimming_pool, :has_hdtv, :has_bathtub,
images: []
)
要将数组或嵌套参数列入白名单,您需要使用哈希作为允许的最后一个参数。 images: []
将允许包含 ActionDispatch::UploadedFile
.
的允许标量数组
如果您想将包含嵌套参数和平面参数的非常规参数列入白名单,您需要更有创意。要记住的关键是 ActionController::Parameters
是一个类似散列的对象,您可以像散列一样操作它:
def property_params
params.require(:data)
.permit(
:title, :description, :max_guests,
:price_per_day, :address, :average_rating,
:has_beach_nearby, :has_beds, :has_kitchen,
:has_swimming_pool, :has_hdtv, :has_bathtub
).merge(
# fetch is like require but does not raise if the key is not present
images: params.fetch(:images, [])
)
end
使用 ActiveStorage,您实际上 need to manually attach the files。
我好像这样解决了:
def update
@property = Property.find(params[:id])
if current_user === @property.user
if params[:images]
@property.images.attach(params[:images])
end
property = @property.update(property_params)
if property
render json: {
success: "Successfully updated",
property: @property,
images: @property.images
}, status: 200
else
render json: {
error: "Error when updating this property",
}, status: 500
end
else
render json: {
error: "You are not authorized to update this property"
}, status: 403
end
end
private
def property_params
json = JSON.parse(params[:data])
json = ActionController::Parameters.new(json)
json.permit(
:title, :description, :max_guests,
:price_per_day, :address, :average_rating,
:has_beach_nearby, :has_beds, :has_kitchen,
:has_swimming_pool, :has_hdtv, :has_bathtub, images: []
)
end
不确定这是否正确,但它似乎有效
我正在尝试使用来自 React 前端的 formData 进行一次 API 调用,该前端具有多个图像加上 strings/booleans 等以更新实体
我正在使用活动存储并且我能够将多个图像附加到实体但是当我想用字符串等更新实体时通过一个 API 调用(理想情况下)。它是这样说的:
param is missing or the value is empty: property
我知道原因是我的formData结构是这样的:
data: {"title": "xxxxxx", "description": "xxxxxx" etc.}, images[]: File, images[]: File etc.
而且我需要 属性 作为键而不是数据:
def property_params
params.require(:property).permit(:title, :description, :max_guests, :price_per_day, :address,:average_rating, :has_beach_nearby, :has_beds, :has_kitchen, :has_swimming_pool, :has_hdtv,:has_bathtub, :images [])
end
但是当我不这样做时,图像无法识别,因为它是不允许的,所以 API 没有收到它
我正在附加这样的图像(并且有效):
if params[:images].present?
params[:images].each do |image|
@property.images.attach(image)
end
end
是否可以使用一次 API 调用上传多张图片和数据?如果没有,我需要做什么?
这是整个 属性 控制器:
class Api::V1::PropertiesController < ApiController
before_action :authenticate_user!, only: [:update, :create, :destroy]
def index
@properties = Property.all
render json: @properties
end
def show
@property = Property.find(params[:id])
render json: @property
end
def update
@property = Property.find(params[:id])
if current_user === @property.user
if params[:images].present?
params[:images].each do |image|
@property.images.attach(image)
end
end
@property.update(property_params)
render json: {
success: "Successfully updated",property: @property},
status: 200
else
render json: {
error: "You are not authorized to update this property"},
status: 403
end
end
private
def property_params
params.require(:property).permit(:title, :description, :max_guests, :price_per_day, :address,:average_rating, :has_beach_nearby, :has_beds, :has_kitchen, :has_swimming_pool, :has_hdtv,:has_bathtub, :images [])
end
被卡住了一段时间,非常感谢任何帮助(Rails 的新手)
Rack 使用括号在表单数据中传递哈希:
irb(main):005:0> Rack::Utils.parse_nested_query("property[title]=foo&property[description]=bar")
=> {"property"=>{"title"=>"foo", "description"=>"bar"}}
可以使用空括号传递数组:
irb(main):008:0> Rack::Utils.parse_nested_query("property[foo][]=a&property[foo]&[]=property[foo][]=c")
=> {"property"=>{"foo"=>nil}}
对于多部分表单数据,您通常会使用表单(可见表单或虚拟表单)并在输入上设置名称属性:
<form action="/properties" method="post" multipart>
<input name="property[images][]" type="file" />
<input name="property[images][]" type="file" />
</form>
Rack 会将请求正文的各个部分拼接在一起并创建单个参数哈希。
你也有语法错误:
# Use sensible line lengths and this won't happen as often...
params.require(:property)
.permit(
:title, :description, :max_guests,
:price_per_day, :address, :average_rating,
:has_beach_nearby, :has_beds, :has_kitchen,
:has_swimming_pool, :has_hdtv, :has_bathtub,
images: []
)
要将数组或嵌套参数列入白名单,您需要使用哈希作为允许的最后一个参数。 images: []
将允许包含 ActionDispatch::UploadedFile
.
如果您想将包含嵌套参数和平面参数的非常规参数列入白名单,您需要更有创意。要记住的关键是 ActionController::Parameters
是一个类似散列的对象,您可以像散列一样操作它:
def property_params
params.require(:data)
.permit(
:title, :description, :max_guests,
:price_per_day, :address, :average_rating,
:has_beach_nearby, :has_beds, :has_kitchen,
:has_swimming_pool, :has_hdtv, :has_bathtub
).merge(
# fetch is like require but does not raise if the key is not present
images: params.fetch(:images, [])
)
end
使用 ActiveStorage,您实际上 need to manually attach the files。
我好像这样解决了:
def update
@property = Property.find(params[:id])
if current_user === @property.user
if params[:images]
@property.images.attach(params[:images])
end
property = @property.update(property_params)
if property
render json: {
success: "Successfully updated",
property: @property,
images: @property.images
}, status: 200
else
render json: {
error: "Error when updating this property",
}, status: 500
end
else
render json: {
error: "You are not authorized to update this property"
}, status: 403
end
end
private
def property_params
json = JSON.parse(params[:data])
json = ActionController::Parameters.new(json)
json.permit(
:title, :description, :max_guests,
:price_per_day, :address, :average_rating,
:has_beach_nearby, :has_beds, :has_kitchen,
:has_swimming_pool, :has_hdtv, :has_bathtub, images: []
)
end
不确定这是否正确,但它似乎有效