Ruby on Rails Paperclip + Dropbox + Heroku issue

811 views Asked by At

I have small project which works locally like a charm, but adding anything with paperclip doesn't work on heroku and also travis is failing the tests because it cant seem to be able to create user. I have no idea whats wrong I have tried everything but I cannot get the images to upload except locally. I have understood that "User model missing required attr_accessor for 'avatar_file_name' " from the heroku logs might be the problem but I dont know what to do with that. Googling has only suggested heroku db migrate and reset and stuff but none of that has helped. Any help is greatly appreciated!

Here is my code and heroku logs:

User

class User < ActiveRecord::Base
  has_secure_password

  has_attached_file :avatar, :styles => { :thumb => "100x100#" },
                    :storage => :dropbox,
                    :dropbox_credentials => Rails.root.join("config/dropbox.yml"),
                    :dropbox_options => {},
                    :path => ":style/:id_:filename"


  validates_attachment_content_type :avatar, :content_type => /\Aimage/


  validates :username, uniqueness: true,
            length: { minimum: 3, maximum: 15 }

  validates :password, :format => {:with => /(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{4,}/,
                                   message: "Password must be at least 4 characters and include one number and one letter."}


  has_many :images
  has_many :videos
  has_many :comments, dependent: :destroy
end

Image class:

class Image < ActiveRecord::Base
  has_attached_file :photo, :styles => { :small => "100x100#", :thumb => "200x200#" },
                    :storage => :dropbox,
                    :dropbox_credentials => Rails.root.join("config/dropbox.yml"),
                    :dropbox_options => {},
                    :path => ":style/:id_:filename"

  validates_attachment_content_type :photo, :content_type => /\Aimage/

  validates_attachment_presence :photo

  validates :name, presence: true,
            length: { minimum: 3, maximum: 25 }

  validates :description, presence: true,
            length: { minimum: 3}


  belongs_to :user
  has_many :comments, dependent: :destroy
  has_many :users, through: :comments

  def to_s
    self.name
  end
end

Schema:

  create_table "images", force: true do |t|
    t.string   "name"
    t.text     "description"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "photo_file_name"
    t.string   "photo_content_type"
    t.integer  "photo_file_size"
    t.datetime "photo_updated_at"
    t.integer  "user_id"
  end

  create_table "users", force: true do |t|
    t.string   "username"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "password_digest"
    t.string   "avatar_file_name"
    t.string   "avatar_content_type"
    t.integer  "avatar_file_size"
    t.datetime "avatar_updated_at"
    t.boolean  "admin"
  end

Heroku logs:

2014-03-17T16:30:41.021699+00:00 app[web.1]: Command :: file -b --mime-type '/tmp/0f4064bf72c14ed980b8ee590beaec4420140317-2-1cdynzs'
2014-03-17T16:30:41.099547+00:00 app[web.1]: Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]' 2>/dev/null
2014-03-17T16:30:41.099547+00:00 app[web.1]: Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]' 2>/dev/null
2014-03-17T16:30:41.273257+00:00 app[web.1]: Command :: identify -format %m '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]'
2014-03-17T16:30:41.273307+00:00 app[web.1]: Command :: identify -format %m '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]'
2014-03-17T16:30:41.334625+00:00 app[web.1]: Command :: convert '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]' -auto-orient -resize "100x" -crop "100x100+0+0" +repage '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y020140317-2-fcrgrr'
2014-03-17T16:30:41.334625+00:00 app[web.1]: Command :: convert '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]' -auto-orient -resize "100x" -crop "100x100+0+0" +repage '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y020140317-2-fcrgrr'
2014-03-17T16:30:41.560659+00:00 app[web.1]: Command :: file -b --mime '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y020140317-2-fcrgrr'
2014-03-17T16:30:41.560659+00:00 app[web.1]: Command :: file -b --mime '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y020140317-2-fcrgrr'
2014-03-17T16:30:41.617261+00:00 app[web.1]: Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]' 2>/dev/null
2014-03-17T16:30:41.61
7261+00:00 app[web.1]: Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]' 2>/dev/null
2014-03-17T16:30:41.744505+00:00 app[web.1]: Command :: identify -format %m '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]'
2014-03-17T16:30:41.797779+00:00 app[web.1]: Command :: convert '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]' -auto-orient -resize "200x" -crop "200x200+0+0" +repage '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y020140317-2-ytve1h'
2014-03-17T16:30:41.797923+00:00 app[web.1]: Command :: convert '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]' -auto-orient -resize "200x" -crop "200x200+0+0" +repage '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y020140317-2-ytve1h'
2014-03-17T16:30:41.744505+00:00 app[web.1]: Command :: identify -format %m '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y0[0]'
2014-03-17T16:30:42.014628+00:00 app[web.1]: Command :: file -b --mime '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y020140317-2-ytve1h'
2014-03-17T16:30:42.014628+00:00 app[web.1]: Command :: file -b --mime '/tmp/5378c8364c1b77c6ea276a4aff6a6aa120140317-2-1b391y020140317-2-ytve1h'
2014-03-17T16:30:42.087179+00:00 app[web.1]: Command :: file -b --mime-type '/tmp/a2135060c6ef6c2fe9585f8c766c905220140317-2-as92rt'
2014-03-17T16:30:42.087505+00:00 app[web.1]: Command :: file -b --mime-type '/tmp/a2135060c6ef6c2fe9585f8c766c905220140317-2-as92rt'
2014-03-17T16:27:18.117648+00:00 heroku[router]: at=info method=GET path=/images/new host=joonaksenmediabox.herokuapp.com request_id=c2526b7a-0934-45b8-9fd3-c808954b061b fwd="88.192.47.126" dyno=web.1 connect=2ms service=47ms status=200 bytes=3215
2014-03-17T16:30:45.558815+00:00 app[web.1]: Completed 500 Internal Server Error in 4600ms
2014-03-17T16:30:45.560996+00:00 app[web.1]: NoMethodError (undefined method `images' for nil:NilClass):
2014-03-17T16:30:45.558815+00:00 app[web.1]: Completed 500 Internal Server Error in 4600ms
2014-03-17T16:30:45.560996+00:00 app[web.1]: 
2014-03-17T16:30:45.560996+00:00 app[web.1]:   app/controllers/images_controller.rb:35:in `block in create'
2014-03-17T16:30:45.560996+00:00 app[web.1]:   app/controllers/images_controller.rb:33:in `create'
2014-03-17T16:30:45.560996+00:00 app[web.1]: 
2014-03-17T16:30:45.560996+00:00 app[web.1]: 
2014-03-17T16:30:45.560996+00:00 app[web.1]: 
2014-03-17T16:30:45.560996+00:00 app[web.1]: NoMethodError (undefined method `images' for nil:NilClass):
2014-03-17T16:30:45.560996+00:00 app[web.1]:   app/controllers/images_controller.rb:35:in `block in create'
2014-03-17T16:30:45.560996+00:00 app[web.1]:   app/controllers/images_controller.rb:33:in `create'
2014-03-17T16:30:45.561209+00:00 app[web.1]: 
2014-03-17T16:30:45.561209+00:00 app[web.1]: 
2014-03-17T16:30:45.563178+00:00 heroku[router]: at=info method=POST path=/images host=joonaksenmediabox.herokuapp.com request_id=3241f336-9814-4074-bb54-e027e20953de fwd="88.192.47.126" dyno=web.1 connect=3ms service=5957ms status=500 bytes=1543
2014-03-17T16:30:45.948938+00:00 heroku[router]: at=info method=GET path=/favicon.ico host=joonaksenmediabox.herokuapp.com request_id=b3c12f71-127a-4b52-8133-8f36d2526bed fwd="88.192.47.126" dyno=web.1 connect=20ms service=20ms status=304 bytes=133
2014-03-17T16:30:50.748761+00:00 heroku[router]: at=info method=GET path=/favicon.ico host=joonaksenmediabox.herokuapp.com request_id=70058206-1727-41fe-894a-6e03ab6441c1 fwd="88.192.47.126" dyno=web.1 connect=1ms service=6ms status=304 bytes=133
2014-03-17T16:31:40.926008+00:00 app[web.1]: Started GET "/signup" for 88.192.47.126 at 2014-03-17 16:31:40 +0000
2014-03-17T16:31:40.935849+00:00 app[web.1]: Processing by UsersController#new as HTML
2014-03-17T16:31:40.926008+00:00 app[web.1]: Started GET "/signup" for 88.192.47.126 at 2014-03-17 16:31:40 +0000
2014-03-17T16:31:40.935849+00:00 app[web.1]: Processing by UsersController#new as HTML
2014-03-17T16:31:40.980751+00:00 app[web.1]: [deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
2014-03-17T16:31:41.056385+00:00 app[web.1]:   Rendered users/_form.html.erb (94.7ms)
2014-03-17T16:31:41.056467+00:00 app[web.1]:   Rendered users/_form.html.erb (94.7ms)
2014-03-17T16:31:41.056738+00:00 app[web.1]:   Rendered users/new.html.erb within layouts/application (97.3ms)
2014-03-17T16:31:41.056738+00:00 app[web.1]:   Rendered users/new.html.erb within layouts/application (97.3ms)
2014-03-17T16:31:41.063475+00:00 app[web.1]:   Rendered layouts/_messages.html.erb (0.7ms)
2014-03-17T16:31:41.061918+00:00 app[web.1]:   Rendered layouts/_navigation_links.html.erb (1.1ms)
2014-03-17T16:31:41.061918+00:00 app[web.1]:   Rendered layouts/_navigation_links.html.erb (1.1ms)
2014-03-17T16:31:41.063475+00:00 app[web.1]:   Rendered layouts/_messages.html.erb (0.7ms)
2014-03-17T16:31:41.063980+00:00 app[web.1]: Completed 200 OK in 128ms (Views: 108.0ms | ActiveRecord: 7.1ms)
2014-03-17T16:31:41.062005+00:00 app[web.1]:   Rendered layouts/_navigation.html.erb (2.7ms)
2014-03-17T16:31:41.062005+00:00 app[web.1]:   Rendered layouts/_navigation.html.erb (2.7ms)
2014-03-17T16:31:41.063980+00:00 app[web.1]: Completed 200 OK in 128ms (Views: 108.0ms | ActiveRecord: 7.1ms)
2014-03-17T16:31:41.083633+00:00 heroku[router]: at=info method=GET path=/signup host=joonaksenmediabox.herokuapp.com request_id=e621ef11-32a5-4332-9614-251c4f2d3daf fwd="88.192.47.126" dyno=web.1 connect=12ms service=160ms status=304 bytes=848
2014-03-17T16:31:41.225087+00:00 heroku[router]: at=info method=GET path=/favicon.ico host=joonaksenmediabox.herokuapp.com request_id=1e94cef8-c9c1-4885-beeb-0318e5c7d865 fwd="88.192.47.126" dyno=web.1 connect=2ms service=7ms status=304 bytes=133
2014-03-17T16:31:50.135749+00:00 app[web.1]: Started POST "/users" for 88.192.47.126 at 2014-03-17 16:31:50 +0000
2014-03-17T16:31:50.135749+00:00 app[web.1]: Started POST "/users" for 88.192.47.126 at 2014-03-17 16:31:50 +0000
2014-03-17T16:31:50.142721+00:00 app[web.1]: Processing by UsersController#create as HTML
2014-03-17T16:31:50.142721+00:00 app[web.1]: Processing by UsersController#create as HTML
2014-03-17T16:31:50.146959+00:00 app[web.1]:   Parameters: {"utf8"=>"✓", "authenticity_token"=>"Orj/xTHYfmjA0CygN4TYDEaui1fTnheoRN4RBKzZNTI=", "user"=>{"username"=>"Joonas", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x007fdf69eea0c0 @tempfile=#<Tempfile:/tmp/RackMultipart20140317-2-1c1sdrz>, @original_filename="kirahvi.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"kirahvi.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Create User"}
2014-03-17T16:31:50.146959+00:00 app[web.1]:   Parameters: {"utf8"=>"✓", "authenticity_token"=>"Orj/xTHYfmjA0CygN4TYDEaui1fTnheoRN4RBKzZNTI=", "user"=>{"username"=>"Joonas", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x007fdf69eea0c0 @tempfile=#<Tempfile:/tmp/RackMultipart20140317-2-1c1sdrz>, @original_filename="kirahvi.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"kirahvi.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Create User"}
2014-03-17T16:31:50.368540+00:00 app[web.1]: Completed 500 Internal Server Error in 217ms
2014-03-17T16:31:50.370827+00:00 app[web.1]: Paperclip::Error (User model missing required attr_accessor for 'avatar_file_name'):
2014-03-17T16:31:50.370827+00:00 app[web.1]: 
2014-03-17T16:31:50.368540+00:00 app[web.1]: Completed 500 Internal Server Error in 217ms
2014-03-17T16:31:50.370827+00:00 app[web.1]:   app/controllers/users_controller.rb:28:in `create'
2014-03-17T16:31:50.370827+00:00 app[web.1]: 
2014-03-17T16:31:50.370827+00:00 app[web.1]:   app/controllers/users_controller.rb:28:in `create'
2014-03-17T16:31:50.370827+00:00 app[web.1]: Paperclip::Error (User model missing required attr_accessor for 'avatar_file_name'):
2014-03-17T16:31:50.370827+00:00 app[web.1]: 
2014-03-17T16:31:50.370827+00:00 app[web.1]: 
2014-03-17T16:31:50.370827+00:00 app[web.1]: 
2014-03-17T16:31:50.370827+00:00 app[web.1]: 
2014-03-17T16:31:50.372412+00:00 heroku[router]: at=info method=POST path=/users host=joonaksenmediabox.herokuapp.com request_id=5ee30c4e-9f01-4008-8a04-2d7bb827bb6c fwd="88.192.47.126" dyno=web.1 connect=1ms service=1213ms status=500 bytes=1543
2014-03-17T16:34:25.778411+00:00 heroku[api]: Starting process with command `bundle exec rake db:schema:load` by [email protected]
2014-03-17T16:34:31.331211+00:00 heroku[run.8399]: Awaiting client
2014-03-17T16:34:31.397155+00:00 heroku[run.8399]: Starting process with command `bundle exec rake db:schema:load`
2014-03-17T16:34:31.346510+00:00 heroku[run.8399]: State changed from starting to up
2014-03-17T16:34:35.805693+00:00 heroku[run.8399]: Process exited with status 0
2014-03-17T16:34:35.818377+00:00 heroku[run.8399]: State changed from up to complete
2014-03-17T16:34:48.454795+00:00 app[web.1]: Started POST "/users" for 88.192.47.126 at 2014-03-17 16:34:48 +0000
2014-03-17T16:34:48.454795+00:00 app[web.1]: Started POST "/users" for 88.192.47.126 at 2014-03-17 16:34:48 +0000
2014-03-17T16:34:48.456278+00:00 app[web.1]: Processing by UsersController#create as HTML
2014-03-17T16:34:48.456278+00:00 app[web.1]: Processing by UsersController#create as HTML
2014-03-17T16:34:48.456528+00:00 app[web.1]:   Parameters: {"utf8"=>"✓", "authenticity_token"=>"Orj/xTHYfmjA0CygN4TYDEaui1fTnheoRN4RBKzZNTI=", "user"=>{"username"=>"Joonas", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x007fdf6a0a4528 @tempfile=#<Tempfile:/tmp/RackMultipart20140317-2-1h591ad>, @original_filename="userimg.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"userimg.png\"\r\nContent-Type: image/png\r\n">}, "commit"=>"Create User"}
2014-03-17T16:34:48.456528+00:00 app[web.1]:   Parameters: {"utf8"=>"✓", "authenticity_token"=>"Orj/xTHYfmjA0CygN4TYDEaui1fTnheoRN4RBKzZNTI=", "user"=>{"username"=>"Joonas", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x007fdf6a0a4528 @tempfile=#<Tempfile:/tmp/RackMultipart20140317-2-1h591ad>, @original_filename="userimg.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"userimg.png\"\r\nContent-Type: image/png\r\n">}, "commit"=>"Create User"}
2014-03-17T16:34:48.561762+00:00 app[web.1]: Completed 500 Internal Server Error in 105ms
2014-03-17T16:34:48.562970+00:00 app[web.1]: Paperclip::Error (User model missing required attr_accessor for 'avatar_file_name'):
2014-03-17T16:34:48.561762+00:00 app[web.1]: Completed 500 Internal Server Error in 105ms
2014-03-17T16:34:48.562970+00:00 app[web.1]: 
2014-03-17T16:34:48.562970+00:00 app[web.1]: 
2014-03-17T16:34:48.562970+00:00 app[web.1]: 
2014-03-17T16:34:48.562970+00:00 app[web.1]: 
2014-03-17T16:34:48.562970+00:00 app[web.1]:   app/controllers/users_controller.rb:28:in `create'
2014-03-17T16:34:48.562970+00:00 app[web.1]:   app/controllers/users_controller.rb:28:in `create'
2014-03-17T16:34:48.562970+00:00 app[web.1]: Paperclip::Error (User model missing required attr_accessor for 'avatar_file_name'):
2014-03-17T16:34:48.562970+00:00 app[web.1]: 
2014-03-17T16:34:48.562970+00:00 app[web.1]: 
2014-03-17T16:34:48.566160+00:00 heroku[router]: at=info method=POST path=/users host=joonaksenmediabox.herokuapp.com request_id=f1395049-9db4-493a-a6f5-61975f32d8a7 fwd="88.192.47.126" dyno=web.1 connect=12ms service=186ms status=500 bytes=1543
2014-03-17T16:34:44.050939+00:00 heroku[router]: at=info method=GET path=/favicon.ico host=joonaksenmediabox.herokuapp.com request_id=cdd7f3e1-e177-4339-9a44-8bb3c4e5f761 fwd="88.192.47.126" dyno=web.1 connect=1ms service=5ms status=304 bytes=133

Here are controller creates:

def create
    @user = User.new(user_params)
    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render action: 'show', status: :created, location: @user }
      else
        format.html { render action: 'new' }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

def user_params
    params.require(:user).permit(:username, :password, :password_confirmation, :avatar)
end

def create
    @image = Image.new(image_params)

    respond_to do |format|
      if @image.save
        current_user.images << @image
        format.html { redirect_to @image, notice: 'Image was successfully submitted.' }
        format.json { render action: 'show', status: :created, location: @image }
      else
        format.html { render action: 'new' }
        format.json { render json: @image.errors, status: :unprocessable_entity }
      end
    end
  end

def image_params
      params.require(:image).permit(:name, :description, :photo)
end
2

There are 2 answers

1
Justin On

Since an image belongs_to a user, you need to specify that when you create an image with something along the lines of

def create
   @image = current_user.images.build(image_params)
   ... 
end

and before you decided to deploy it to Heroku, you should test that everything works in your development environment. When you create an Image, either through the rails console or in your view, check what the user_id is: ie- check whether or not it's being associated with a user.

0
opticon On

What version of rails are you using?

You may need to add

attr_accessible :avatar_file_name, :avatar_file_size...

...etc to your user model. I seem to recall having a similar problem, and something like:

attr_accessor :avatar_file_name

Did the trick. Heroku and Paperclip can be kind of a pain to debug because of the barriers between you and the server, but keep at it! Let me know if either of those solutions works or at least changes the error you're receiving.