Vue Js和Rails:图片上传

时间:2020-06-19 06:43:03

标签: ruby-on-rails vuejs2 rails-activestorage

我正在尝试使用gem active存储将图像上传到我的rails API,并通过Vue应用程序将其作为FormData发送。但是,即使所有参数都已发送,它也会产生param is missing or the value is empty错误。

Vue Js(组件)

async onSubmit(e){
          const formData = await new FormData()
          formData.append('name', this.name)
          formData.append('description', this.description)
          formData.append('country_id', this.country[0].id)
          formData.append('image', this.selectedFile)
          this.addDish(formData);
      }

Vuex

async addDish({ commit }, formData){
        const response = await axios.post(URL,formData);
        commit('newDish', response.data);
    },

轨道模型

class Dish < ApplicationRecord
  has_one_attached :image
end

滑行控制器

def create
dish = Dish.new(dish_params)
if dish.save
 render json: dish, status: :created
else
 render json: dish.errors, status: :unprocessable_entity
end
end 

private
def dish_params
  params.require(:dish).permit(:name, :description, :country_id, :image)
end

API错误

 Parameters: {"name"=>"teste", "description"=>"teste", "country_id"=>"1", 
"image"=>#<ActionDispatch::Http::UploadedFile:0x00005584f2f458e0 
@tempfile=#<Tempfile:/tmp/RackMultipart20200619-4-o32kdp.png>, @original_filename="0.png",
 @content_type="image/png", 
@headers="Content-Disposition: form-data; name=\"image\"; filename=\"0.png\"\r\nContent-Type: image/png\r\n">}
2020-06-19T06:20:28.183600+00:00 app[web.1]: I, [2020-06-19T06:20:28.183538 #4]  INFO -- : [c510b9d0-df62-4479-a4ef-1b898d113fcc] 
Completed 400 Bad Request in 1ms (ActiveRecord: 0.0ms | Allocations: 163)
2020-06-19T06:20:28.184035+00:00 app[web.1]: F, [2020-06-19T06:20:28.183978 #4] FATAL -- : [c510b9d0-df62-4479-a4ef-1b898d113fcc]
2020-06-19T06:20:28.184048+00:00 app[web.1]: [c510b9d0-df62-4479-a4ef-1b898d113fcc] 
ActionController::ParameterMissing (param is missing or the value is empty: dish):

1 个答案:

答案 0 :(得分:0)

该错误来自以下事实:您在请求中需要密钥:dish,但没有发送它。让我们看看

在Rails控制器中,您有以下before_action

def dish_params
  params.require(:dish).permit(:name, :description, :country_id, :image)
end

在这里,您说请求必须有一个带有盘名称的键,并且该键必须是一个带有键名称,描述,contryID和图像的符号。因此,请求应该以这种方式构造

requestobject
   dish
       name
       description
       image
       contryID

但是,在您的前端,您没有在请求中提供dish键名,而是将表单的内容散布到请求中,因此您的请求最终会像这样

requestobject
   name
   description
   image
   contryID

如您所见,所有值都存在,但是由于before_action希望它们位于名称为dish的对象中,因此才出现错误

ActionController::ParameterMissing (param is missing or the value is empty: dish):

如错误所示,在请求中未定义盘键。

此问题的解决方案是,当您发送请求时,出于在请求内传播表单数据的目的,请在dish键名内传播请求,如下所示:

async addDish({ commit }, formData){
        const request = {
             dish: formData
         };

        const response = await axios.post(URL, request);
        commit('newDish', response.data);
    },

如您所见,请求对象具有一个名为dish的密钥,由于现在已履行合同,因此您的控制器将得到满足