1

I have rails app that I created so I could use the API portion of things. I can successfully upload a file to the DB of the rails app using curl, but I can't figure out how I could limit the filetype / content type to just CSV.

csv_file.rb #model

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 #controller

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
ipatch
  • 3,933
  • 8
  • 60
  • 99
  • Are you asking if this should work? Or did you try this and it didn't work? – Elvn Oct 17 '15 at 20:03
  • The current code is implemented, and appears to be not working, as I am able to upload files that aren't CSV. – ipatch Oct 17 '15 at 20:05
  • What shows/tells you it's not working? – Elvn Oct 17 '15 at 20:09
  • I'm still able to upload files that aren't CSV. – ipatch Oct 17 '15 at 20:22
  • Try adding the `raise_errors: true` option to the `attachment` definition to see what happens. – Mohamad Oct 18 '15 at 13:48
  • @Mohamad I added the `raise_errors: true` option to the `attachment` definition in the model, and I'm still able to upload files that are not CSV. Which I am trying to prohibit all files that are not CSV from being uploaded. – ipatch Oct 18 '15 at 17:35

2 Answers2

1

I can't see anything wrong with your code, so this may be a bug in Refile. The only thing I can suggest is a work around using a custom validator.

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

You may want to use the file extension instead because the content_type is not available sometimes.

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

I wouldn't trust the client on this stuff, but even Refile depends on the client for content_type so it makes little different.

Mohamad
  • 34,731
  • 32
  • 140
  • 219
  • I tried putting both of your examples in my `csv_file.rb` model file, but rails is still giving me an error, `NameError (undefined local variable or method `csv_filename' for #): app/models/csv_file.rb:16:in `csv_extension' app/controllers/api/v1/csv_files_controller.rb:41:in `create' – ipatch Oct 19 '15 at 00:00
  • Something is wrong with your setup. Refile will grab the attachment definition, *csv* in this case, and append *_fulename* to it. The same for size and content_type. So I would double check what's going on there. If your code above is correct you shouldn't get this error from Rails. Ps: are you using the gem from master? What version are you using? – Mohamad Oct 19 '15 at 00:04
  • In my `Gemfile` for the rails app I have the following lines, `gem 'refile', require: 'refile/rails' gem 'refile-mini_magick'` Would you care to discuss this further in the Ruby chat room hosted on chat.stackoverflow.com ? – ipatch Oct 19 '15 at 00:52
  • You need to use master from Github. Change the first line to `gem 'refile', github: 'refile/refile', require: 'refile/rails'` – Mohamad Oct 19 '15 at 02:36
0

So there ended up being a couple of problems.

First, the strong parameters in the controller should look like the following,

def csv_params
    params.permit(:csv_file)
end

Secondly, I needed to add a column in a migration as such,

add_column :csv_files, :csv_file_id, :string

Finally, I was able to modify the csv_file.rb model file and add the following line.

attachment :csv_file, extension: "csv"

As it stands now, only files with an extension of .csv can be uploaded to the API.

ipatch
  • 3,933
  • 8
  • 60
  • 99