Загрузить изображение из React в Rails API с Carrierwave - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь загрузить изображения из моего приложения реакции в API рельсов с помощью самоцвета carrierwave.До этого момента я пробовал много вещей и искал повсюду в Интернете, не находя решения.

это запрос, который я посылаю запрос от реагировать

, нов приложении rails параметр события не передается

07: 57: 37 api.1 |Запущен PATCH "/ api / v1 / events / 8" для 127.0.0.1 в 2018-05-24 07:57:37 -0600 07:57:37 api.1 |Обработка Api :: V1 :: EventsController # обновляется как / 07:57:37 api.1 |
Параметры: {"id" => "8"} 07:57:37 api.1 |Загрузка события (4,9 мс) SELECT events. * ОТ events ГДЕ events. id = 8 ПРЕДЕЛ 1 07:57:37 api.1 |Выполнено 401 несанкционированным в 7 мс (ActiveRecord: 4,9 мс) 07:57:37 api.1 |07:57:37 api.1 |07:57:37 api.1 |07:57:37 api.1 |ActionController :: ParameterMissing (параметр отсутствует или значение пусто: событие): 07:57:37 api.1 |07:57:37 api.1 |app / controllers / api / v1 / events_controller.rb: 92: в event_params' 07:57:37 api.1 | app/controllers/api/v1/events_controller.rb:56:in update '

Если я отправил с использованием JSON.Stringify в теле запроса, он попадет в функцию обновления, ноcarrierwave ничего не делает.

Я знаю, что Carrierwave работает, потому что если загрузка изображения с помощью ActiveAdmin работает нормально.

Вот действие, в котором я создаю запрос

export const uploadMainImage = (event, eventId) => {

    return (dispatch) => {
        //dispatch({ type: UPLOAD_IMAGE_REQUEST });
        //console.log(window.location);
        let upload = {
            event
        }
        const requestOptions = {
            method: 'PATCH',
            headers: uploadAuthHeader(),
            body: upload
        };
        console.log("request:");
        console.log(requestOptions);
        //window.fetch(window.location.origin + '/api/v1/events/image_upload/' + eventId, requestOptions)
        window.fetch(window.location.origin + '/api/v1/events/' + eventId, requestOptions)
          .then(response => response.json())
          .then(response => {
              dispatch({ type: UPLOAD_IMAGE_SUCCESS, payload: response });
          })
          .catch(error => {
                //console.log(error);
                dispatch({ type: UPLOAD_IMAGE_FAILURE, payload: error })
          })
    };
}

Это заголовки:

export function uploadAuthHeader() {
    // return authorization header with jwt token
    let user = JSON.parse(localStorage.getItem('user'));

    if (user && user.auth_token) {
        return { 

            //'Content-Type': 'application/json',
            'Content-Type': 'multipart/form-data',
            'Authorization': 'Bearer ' + user.auth_token 
        };
    } else {
        return {};
    }
}

Здесь я управляю выбором файлов из реагирующей зоны сброса

readFile(files) {


        const event = {
            imagen: files[0]
        }

        this.props.uploadMainImage(event, this.props.match.params.eventId);

    }

На стороне рельса это моя модель

class Event < ApplicationRecord
  belongs_to :user
  mount_uploader :imagen, ImagenUploader
end

и Uploader from Carrierwave не был изменен по умолчанию.

UPDATE ------ Это мой event_controller.rb, я использую метод udate по умолчанию для контроллера

module Api
  module V1
    class EventsController < ApiController
      before_action :authenticate_request, only: [:index, :create, :destroy]
      before_action :set_event, only: [:show, :update, :destroy, :image_upload]


      # GET /events
      # Entrego los eventos especificos del usuario loggeado.
      def index
        @events = @current_user.events
        if params[:page]
          @events = @events.page(params[:page]).per(params[:per_page])
          pageCount = @events.total_pages
        else
          #@events = Event.order('fecha ASC')
          pageCount = 1
        end
        render json: { events: @events, meta: { pages: pageCount, records: @events.count } }
      end

      # GET /events/1
      def show
        render json: @event
      end

      # GET /events/upcoming
      def upcoming
        @events = Event.where('fecha >= ?', Date.today).order(:fecha)
        if params[:page]
          @events = @events.page(params[:page]).per(params[:per_page])
          pageCount = @events.total_pages
        else
          #@events = Event.order('fecha ASC')
          pageCount = 1
        end

        render json: { events: @events, meta: { pages: pageCount, records: Event.count } }
      end

      # POST /events
      def create
        @event = Event.new(event_params)
        #@event.imagen = event_params[:imagen][:preview]

        if @event.save
          #@event.imagen = event_params[:imagen][:preview]
          render json: @event, status: :created#, location: @event
        else
          render json: @event.errors, status: :unprocessable_entity
        end
      end

      # PATCH/PUT /events/1
      def update
        if @event.update(event_params)
          render json: @event
        else
          render json: @event.errors, status: :unprocessable_entity
        end
      end


      # DELETE /events/1
      def destroy
        @event.destroy
      end

      private
        # Use callbacks to share common setup or constraints between actions.
        def set_event
          @event = Event.find(params[:id])
        end

        # Only allow a trusted parameter "white list" through.
        def event_params
          params.require(:event).permit!
        end
    end
  end
end

Также из Active Admin, файл event.rb, я только что разрешил поле: imagen, и когда я загружаю из активного администратора, оно отлично работает без каких-либо изменений в контроллере.

ActiveAdmin.register Event do
# See permitted parameters documentation:
# https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters
#
# permit_params :list, :of, :attributes, :on, :model
#
# or
#
# permit_params do
#   permitted = [:permitted, :attributes]
#   permitted << :other if params[:action] == 'create' && current_user.admin?
#   permitted
# end
permit_params :nombre, :user_id, :hora, :fecha, :lugar, :meta, :inicio_inscripcion, 
    :fin_inscripcion, :costo_inscripcion, :pagina_web, :logo, :numero_inicial, 
    :nombre_contacto, :telefono_contacto, :email_contacto, :imagen, :string

end

Пожалуйста, мне нужна рука, чтобы выяснить, как загрузить IMAиз моего приложения React в Rails API.

Второе ОБНОВЛЕНИЕ

Это запрос POST от active_admin

Запущен POST "/ admin / events / 6" для ::1 в 2018-05-24 11:54:48 -0600 11:54:48 api.1 |Обработка Admin :: EventsController # обновляется как HTML 11:54:48 api.1 |Параметры: { "UTF-8" => "✓", "authenticity_token" => "9BqST8qDLEJbDlfd6Xs / + YCDMy9qPeCcbOOxbjIGbDoTBRaGAVRU48rqI + E3kD9ORbsiBguS / emJN9JIM + StuQ ==", "событие" => { "идентификатор_пользователя" => "1", "Nombre"=> "Carrera con Foto", "hora_inicio (1i)" => "2018", "hora_inicio (2i)" => "5", "hora_inicio (3i)" => "24", "hora_inicio (4i)"=> "", "hora_inicio (5i)" => "", "fecha_inicio (1i)" => "", "fecha_inicio (2i)" => "", "fecha_inicio (3i)" => "", "hora (1i) "=>" 2018 "," hora (2i) "=>" 5 "," hora (3i) "=>" 24 "," hora (4i) "=>" "," hora (5i) "=>" "," fecha (1i) "=>" 2018 "," fecha (2i) "=>" 5 "," fecha (3i) "=>" 27 "," lugar "=>" ВиллаOlimpica "," meta "=>" "," inicio_inscripcion (1i) "=>" 2018 "," inicio_inscripcion (2i) "=>" 5 "," inicio_inscripcion (3i) "=>" 17 "," fin_inscripcion (1i) "=>" 2018 "," fin_inscripcion (2i) "=>" 5 "," fin_inscripcion (3i) "=>" 25 "," costo_inscripcion "=>" 123 "," pagina_web "=>" ","logo" => "", "Numberro_inicial" => «100», «nombre_contacto» => «Гектор Торо», «telefono_contacto» => «50498761065», «email_contacto» => «htorohn@gmail.com», "imagen "=> #, @ original_filename =" IMG_0008.PNG ",@ content_type = "image / png", @ headers = "Content-Disposition: form-data;имя = \ "событие [Imagen] \";filename = \ "IMG_0008.PNG \" \ r \ nContent-Type: image / png \ r \ n ">}," commit "=>« Обновить событие »,« id »=>« 6 »}

ОБНОВЛЕНИЕ 3.

Я внес изменения, предложенные Биллом, однако параметр события все еще не попадает в приложение rails.

07: 59: 02 api.1 | Started PATCH "/api / v1 / events / 8 "для 127.0.0.1 в 2018-05-25 07:59:02 -0600 07:59:02 api.1 | Обработка Api :: V1 :: EventsController # обновляется как / 07:59:02 api.1 | Параметры: {"id" => "8"} 07:59:02 api.1 | Загрузка события (0,7 мс) SELECT events. * ОТ events ГДЕevents. id = 8 LIMIT 1 07: 59: 02 api.1 |Выполнено 401 несанкционированным в 8 мс (ActiveRecord: 0,7 мс) 07:59:02 api.1 |07:59:02 api.1 |07:59:02 api.1 |
07:59:02 api.1 |ActionController :: ParameterMissing (параметр отсутствует или значение пусто: событие): 07:59:02 api.1 |
07:59:02 api.1 |app / controllers / api / v1 / events_controller.rb: 95: в event_params' 07:59:02 api.1 | app/controllers/api/v1/events_controller.rb:56:in update '

введите описание изображения здесь

1 Ответ

0 голосов
/ 24 мая 2018

Итак, если посмотреть на параметры, разрешенные вашим активным администратором, и параметры, разрешенные вашим собственным EventsController, то, похоже, существует несоответствие между тем, что разрешено и ожидаемо, по сравнению с тем, что вы отправляете из своего Javascript.Я экстраполирую вашу events схему таблицы из вашего кода.Я не могу воспроизвести твой код локально, потому что у меня нет всего этого.Но вот что, я думаю, сработает:

Вам нужно передать данные файла изображения в теле, как вы пытались, но его нужно кодировать в теле с именем параметра (event[imagen]),Попробуйте это:

export const uploadMainImage = (imageFile, eventId) => {

    let data = new FormData();
    data.append("event[imagen]", imageFile);

    return (dispatch) => {
        //dispatch({ type: UPLOAD_IMAGE_REQUEST });
        //console.log(window.location);
        const requestOptions = {
            method: 'PATCH',
            headers: uploadAuthHeader(),
            body: data
        };
        console.log("request:");
        console.log(requestOptions);
        window.fetch(window.location.origin + '/api/v1/events/' + eventId, requestOptions)
          .then(response => response.json())
          .then(response => {
              dispatch({ type: UPLOAD_IMAGE_SUCCESS, payload: response });
          })
          .catch(error => {
                //console.log(error);
                dispatch({ type: UPLOAD_IMAGE_FAILURE, payload: error })
          })
    };
}


readFile(files) {
    var imageFile = files[0];  // assumes files[0] is from your file form input
    this.props.uploadMainImage(imageFile, this.props.match.params.eventId);
}
...