Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails: Dropzone js, getting [object Object], but why?

I'm getting [object Object] on my thumbnails (the background image is the area where you can click on to upload photos... I'm not sure how to load up the normal box similar to the example in http://www.dropzonejs.com/)

enter image description here

View

<%= simple_form_for @project do |f| %>

  <div class="dropzone dz-clickable dz-square" id="mydrop">
    <div class="dz-default dz-message" data-dz-message=""></div>
    <div id="bi_previews"></div>
    <div class="fallback">
      <%= f.file_field :beautiful_image %></div>
    </div>
  </div>

<% end %>

CoffeeScript

$(document).on 'ready page:load', ->
  Dropzone.autoDiscover = false
  $('div#mydrop').dropzone 
    url: '/projects'
    previewsContainer: "#bi_previews"
    headers: "X-CSRF-Token" : $('meta[name="csrf-token"]').attr('content')
    paramName: "project[beautiful_image]"
    init: ->
      @on 'success', (file, json) ->
      @on 'addedfile', (file) ->
      @on 'drop', (file) ->
        alert 'file'
        return
      return

routes.rb

Rails.application.routes.draw do
  devise_for :users
  resources :projects

controller

def project_params
  params.require(:project).permit(
    :user_id, :beautiful_image, :title_name, :remove_project_images_files, project_images_files: [],
    project_images_attributes: [:id, :project_id, :photo, :_destroy]).merge(user_id: current_user.id)
end

model

has_attached_file :beautiful_image, :styles => { :large => "800x800>", :medium => "500x500>", :thumb => "150x150#" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :beautiful_image, content_type: /\Aimage\/.*\Z/

EDIT

Posting controller per comment requets

def new
  @project = Project.new
  @gear = Gear.new
  @project.gears.build
  @project.project_images.build
end

def edit
  @project = Project.find(params[:id])
end

def create
  @project = Project.new(project_params)

  respond_to do |format|
    if @project.save
      format.html { redirect_to @project, notice: 'Project was successfully created.' }
      format.json { render :show, status: :created, location: @project }
    else
      format.html { render :new }
      format.json { render json: @project.errors, status: :unprocessable_entity }
    end
  end
end
like image 506
hellomello Avatar asked Jul 18 '15 22:07

hellomello


1 Answers

In Rails You can't post data without using form. Rails verifies the CSRF token for each request unless token_authentication is turned off.In your code, you initialized dropzone using div ID. So server can't verify your authenticity token.

The ApplicationController called protect_from_forgery, as appropriate. All of the controllers inherited from ApplicationController, and it appeared that there were no CSRF vulnerabilities. Through dynamic analysis, however, I discovered that the application was, in fact, vulnerable to CSRF.

So initialize your dropzone using id of the form.

HTML code

<%= simple_form_for @project, class: 'dropzone', id: 'project-form' do |f| %>
            <div class="fallback">
              <%= f.file_field :beautiful_image, multiple: true %>
            </div>
 <% end %>

and your Javascript should like this

   var objDropZone;
   Dropzone.autoDiscover = false;
   $("#project-form").dropzone({
            acceptedFiles: '.jpeg,.jpg,.png',
            maxFilesize: 5, //In MB
            maxFiles: 5,
            addRemoveLinks: true,
            removedfile: function (file) {
                if (file.xhr.responseText.length > 0) {
                    var fileId = JSON.parse(file.xhr.responseText).id;
                        $.ajax({
                        url: '/projects/' + fileId,
                        method: 'DELETE',
                        dataType: "json",
                        success: function (result) {
                           console.log('file deleted successfully');
                            var _ref;
                            return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;

                        },
                        error: function () {
                          console.log('error occured while deleteing files');
                        }

                    });
                }

            },
            init: function () {
                objDropZone = this;

                this.on("success", function (file, message) {
                    console.log('file uploaded successfully')
                });

                this.on("error", function (file, message) {
                    var _ref;
                    return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;
                });
             }
        });
like image 181
Bibek Sharma Avatar answered Nov 01 '22 20:11

Bibek Sharma