Как добавить проверку для перезаписи в приложении rails?

У меня есть приложение rails, которое я создал, чтобы я мог использовать часть API. Я могу успешно загрузить файл в БД приложения rails с помощью curl, но я не могу понять, как я могу ограничить тип файла/тип контента только CSV.

csv_file.rb #модель

class CsvFile < ActiveRecord::Base
    # attachment :content_type => "text/csv"
    # http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to/
    attachment :csv, extension: "csv", content_type: "text/csv"
end

csv_files.rb #контроллер

class API::V1::CsvFilesController < ApplicationController

  # see http://stackoverflow.com/questions/15040964/ for explanation
  skip_before_filter :verify_authenticity_token

  def index
    @csv_files = CsvFile.all
    if @csv_files
      render json: @csv_files,
        # each_serializer: PictureSerializer,
        root: "csv_files"
    else
      @error = Error.new(text: "404 Not found",
                          status: 404,
                          url: request.url,
                          method: request.method)
      render json: @error.serializer
    end 
  end

  def show
    if @csv_file
      render json: @csv_file,
              # serializer: PictureSerializer,
              root: "csv_file"
    else
      @error = Error.new(text: "404 Not found",
                          status: 404,
                          url: request.url,
                          method: request.method)
      render json: @error.serializer
    end
  end

  # POST /csv_files.json
  def create
    @csv_file = CsvFile.new(csv_params)

    if @csv_file.save
      render json: @csv_file,
        # serializer: PictureSerializer, 
        meta: { status: 201,
          message: "201 Created"},
          root: "csv_file"
    else
      @error = Error.new(text: "500 Server Error",
        status: 500,
        url: request.url,
        method: request.method)
      render :json => @error.serializer
    end
  end

  def update
  end

  def delete
  end

  private

  def csv_params

  end
end

person ipatch    schedule 17.10.2015    source источник
comment
Вы спрашиваете, должно ли это работать? Или вы пробовали это, и это не сработало?   -  person Elvn    schedule 17.10.2015
comment
Текущий код реализован и, похоже, не работает, так как я могу загружать файлы, отличные от CSV.   -  person ipatch    schedule 17.10.2015
comment
Что показывает/говорит вам, что это не работает?   -  person Elvn    schedule 17.10.2015
comment
Я по-прежнему могу загружать файлы, отличные от CSV.   -  person ipatch    schedule 17.10.2015
comment
Попробуйте добавить параметр raise_errors: true к определению attachment, чтобы посмотреть, что произойдет.   -  person Mohamad    schedule 18.10.2015
comment
@Mohamad Я добавил параметр raise_errors: true к определению attachment в модели, и я по-прежнему могу загружать файлы, отличные от CSV. Что я пытаюсь запретить загружать все файлы, кроме CSV.   -  person ipatch    schedule 18.10.2015


Ответы (2)


Я не вижу ничего плохого в вашем коде, так что это может быть ошибка в Refile. Единственное, что я могу предложить, это обходной путь с использованием пользовательского валидатора.

validate :csv_extension

private

def csv_extension
  unless csv_content_type == "text/csv"
    errors.add :csv, "format must be csv" # might want to use i18n here.
  end
end

Вместо этого вы можете использовать расширение файла, потому что content_type иногда недоступно.

def csv_extension
  unless File.extname(csv_filename) == "csv"
    errors.add :csv, "format must be csv"
  end
end

Я бы не стал доверять клиенту в этом вопросе, но даже Refile зависит от клиента для content_type, так что это мало чем отличается.

person Mohamad    schedule 18.10.2015
comment
Я попытался поместить оба ваших примера в свой файл модели csv_file.rb, но rails по-прежнему выдает мне ошибку, NameError (undefined local variable or method csv_filename' for #‹CsvFile id: nil, created_at: nil, updated_at: nil, csv_id: nil›): app/models/ csv_file.rb:16:в csv_extension' app/controllers/api/v1/csv_files_controller.rb:41:in create' - person ipatch; 19.10.2015
comment
Что-то не так с вашей настройкой. Refile захватит определение вложения, в данном случае csv, и добавит к нему _fulename. То же самое для размера и content_type. Так что я бы еще раз проверил, что там происходит. Если ваш код выше правильный, вы не должны получать эту ошибку от Rails. Ps: вы используете драгоценный камень от мастера? Какую версию ты используешь? - person Mohamad; 19.10.2015
comment
В моем приложении Gemfile для rails у меня есть следующие строки: gem 'refile', require: 'refile/rails' gem 'refile-mini_magick' Не могли бы вы обсудить это в чате Ruby, размещенном на chat.stackoverflow.com? - person ipatch; 19.10.2015
comment
Вам нужно использовать master из Github. Измените первую строку на gem 'refile', github: 'refile/refile', require: 'refile/rails' - person Mohamad; 19.10.2015

Так что в итоге возникла пара проблем.

Во-первых, сильные параметры в контроллере должны выглядеть следующим образом:

def csv_params
    params.permit(:csv_file)
end

Во-вторых, мне нужно было добавить столбец в миграцию как таковую,

add_column :csv_files, :csv_file_id, :string

Наконец, мне удалось изменить файл модели csv_file.rb и добавить следующую строку.

attachment :csv_file, extension: "csv"

Сейчас в API можно загружать только файлы с расширением .csv.

person ipatch    schedule 22.10.2015