17

I then want to use Paperclip to have photos for each Listing. I added the appropriate code to the listings show.html.erb, the listing.rb model, the listings_controller.rb and the _form.html.erb partial.

When I try uploading an image for the Listing I get this error:

Paperclip::Error in ListingsController#update
Listing model missing required attr_accessor for 'avatar_file_name'

Line 44 of listings_controller:

def update
 respond_to do |format|
  if @listing.update(listing_params)
    format.html { redirect_to @listing, notice: 'Listing was successfully updated.' }
    format.json { head :no_content }
  else

A few things to try: namely adding some code to the listing.rb model to make the acceptable images for the :avatar more robust. Here is what several stackoverflow posts mentioned adding to the listing.rb model:

validates_attachment_content_type :avatar, :content_type => %w(image/jpeg image/jpg image/png) 

Unfortunately I still get the same error when I attach an image. When I don't attach an image my default image is loaded fine and the listing is created properly.

My Listing model:

class Listing < ActiveRecord::Base
  has_attached_file :avatar, :styles => { :medium => "150x", :thumb => "100x100>" },   :default_url => "default.jpg"
  validates_attachment_content_type :avatar, :content_type => %w(image/jpeg image/jpg image/png) 
end

My _form.html.erb partial:

<%= form_for @listing, :html => { :multipart => true } do |f| %>
  <% if @listing.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@listing.errors.count, "error") %> prohibited this listing from being saved:</h2>

      <ul>
      <% @listing.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="form-group">
    <%= f.label :name %><br>
    <%= f.text_field :name, class: "form-control" %>
  </div>
  <div class="form-group">
    <%= f.label :company %><br>
    <%= f.text_field :company, class: "form-control" %>
  </div>
  <div class="form-group">
    <%= f.label :email %><br>
    <%= f.text_field :email, class: "form-control" %>
  </div>
  <div class="form-group">
    <%= f.label :phone %><br>
    <%= f.text_field :phone, class: "form-control" %>
  </div>
  <div class="form-group">
    <%= f.label :avatar %><br>
    <%= f.file_field :avatar, class: "form-control" %>
  </div>
  <div class="form-group">
    <%= f.submit class: "btn btn-primary" %>
  </div>
<% end %>

My listings_controller.rb controller:

 def update
    respond_to do |format|
      if @listing.update(listing_params)
        format.html { redirect_to @listing, notice: 'Listing was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @listing.errors, status: :unprocessable_entity }
      end
    end
  end
...
def listing_params
   params.require(:listing).permit(:name, :company, :email, :phone, :avatar)
end

And my schema.rb file

ActiveRecord::Schema.define(version: 20140329174335) do

  create_table "listings", force: true do |t|
    t.string   "name"
    t.string   "company"
    t.string   "email"
    t.string   "phone"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

EDIT: Adding console output after running $rails generate paperclip listing avatar

(I need 10 reputation points to put in post so you have to settle for link https://i.stack.imgur.com/RYxWh.png)

lachlanjc
  • 148
  • 1
  • 5
JJThaeler
  • 203
  • 1
  • 3
  • 9
  • Did you include :avatar as an allowed parameter in `listing_params`? –  Mar 30 '14 at 16:32
  • This should be his problem indeed. Within def listing_params you should have the following at the very least: params.require(:listing).permit(:avatar, :avatar_file_name) – rails4guides.com Mar 30 '14 at 16:40
  • 1
    @rails4guides.com, actually you should not need `:avatar_file_name` in the params, just `:avatar` should be enough as Paperclip handles it's own attributes itself. Or put it another way, I've not needed to specify it in my apps. –  Mar 30 '14 at 16:45
  • You should think so. However, I do remember having seen a github issue where it actually seemed necessary. – rails4guides.com Mar 30 '14 at 16:47
  • I did add :avatar in the listing_params in the listings_controller. I also tried :avatar_file_name just for good measure and still have the same error. – JJThaeler Mar 30 '14 at 16:50
  • 2
    @JJThaeler I think you forgot to create the corresponding fields of `avatar` in `listings` table. – Kirti Thorat Mar 30 '14 at 16:53
  • Did you remember to create the `avatar` column in the `listings` table? –  Mar 30 '14 at 16:54
  • When I generated Paperclip I included the Avatar field. From the Paperclip Git page (https://github.com/thoughtbot/paperclip) I followed this (under Migrations section) for my migration: "Or you can use migration generator: rails generate paperclip user avatar" – JJThaeler Mar 30 '14 at 17:07
  • @JJThaeler Why are you running `rails generate paperclip user avatar` ? It should not be on `user` as you want to use it on `listing`. See my updated answer. – Kirti Thorat Mar 30 '14 at 20:42
  • @kirti I was just copy pasting what the Git page for Paperclip said. I used "rails generate paperclip listing avatar" – JJThaeler Mar 31 '14 at 11:51

3 Answers3

29

I suppose you forgot to create the corresponding fields for avatar in listings table.

I would suggest you to generate a migration to add avatar to listings table as below:

rails generate paperclip listing avatar

Then run rake db:migrate

UPDATE

As per your comments and EDIT, you have a migration file to add avatar to listings table which you created by running rails generate paperclip user avatar but unfortunately for some reason its not going through i.e., there are no avatar specific fields("avatar_file_name", "avatar_content_type", "avatar_file_size" and "avatar_updated_at") in listings table as per your db/schema.rb. This is a very strange behavior.

I would suggest you to follow the below mentioned steps in order:

Destroy the existing migration, if any:

rails destroy paperclip listing avatar  

Generate a new migration:

rails generate paperclip listing avatar

Run

rake db:migrate

UPDATE 2

I hope you did not down voted me (but someone did), so I would like to bring it to notice that it is an ongoing issue with Paperclip and I did suggest a solution in my comments (Mar 31) as below:

I want you to try as gem 'paperclip', :git => "git://github.com/thoughtbot/paperclip.git" in Gemfile and then bundle install. Let me know when you finish

Apparently it wasn't noticed by you or someone who down voted me today. Also, you said No errors as far as I can tell, image here: i.imgur.com/c8KGTa3.png BUT if you look at the output there is an error stating clearly:

migration_file_name': protected methodmigration_file_name' called for PaperclipGenerator:0x007fb3c6494c20 (NoMethodError)

Kirti Thorat
  • 52,578
  • 9
  • 101
  • 108
  • I did do this - see above comment. – JJThaeler Mar 30 '14 at 17:33
  • BUT did you run the migration? Check fields of `listings` table in the `db/schema.rb` file. It should have 4 fields named "avatar_file_name", "avatar_content_type", "avatar_file_size" and "avatar_updated_at". If they are not present then you didn't run the migration. – Kirti Thorat Mar 30 '14 at 17:36
  • Yep, ran rake several times. Above I've added my schema.rb file. – JJThaeler Mar 30 '14 at 17:54
  • Clearly you don't have the paperclip specific fields. See my updated answer to resolve the issue. – Kirti Thorat Mar 30 '14 at 18:12
  • @JJThaeler Yes, see the updated answer.. :) It is much clear. – Arup Rakshit Mar 30 '14 at 18:53
  • @JJThaeler your schema does not have fields for avtar related attributes. You should add a new migration to alter listings table and add those attributes. Use add_attachment :users, :avatar in that migration file. – Alok Anand Mar 30 '14 at 19:59
  • @KirtiThorat why are you destroying existing and regenerating paperclip files for listing? A simple new migration file to alter listings table would do the needful. – Alok Anand Mar 30 '14 at 20:02
  • @AlokAnand See my UPDATE section as to why I suggested to destroy existing migration. – Kirti Thorat Mar 30 '14 at 20:12
  • 1
    @KirtiThorat that's ok, but I still say it is not needed and I suspect avatar attributes are there but in users table as he ran rails generator for paperclip avatar by pointing user model class. – Alok Anand Mar 30 '14 at 20:30
  • @AlokAnand +1 Good Catch. It should not be on `user` as OP wants to use it on `listing`. – Kirti Thorat Mar 30 '14 at 20:41
  • I have followed these exact instructions and my schema file does not have any avatar content in the listings table – JJThaeler Mar 31 '14 at 11:54
  • @JJThaeler Thanks for clarifying. What output do you get when you run `rails generate paperclip listing avatar` and `rake db:migrate`. It would be helpful if you could share that. – Kirti Thorat Mar 31 '14 at 20:37
  • Ohh.. Now I get it. Source Paperclip gem from Github. Update the Gemfile for Paperclip gem with `gem 'paperclip', :git => "git://github.com/thoughtbot/paperclip.git"` and run `bundle install` and try again. – Kirti Thorat Mar 31 '14 at 20:48
  • @kirti Yep I did that too following this (https://github.com/thoughtbot/paperclip/issues/1495) recommendation. I've posted this as an issue on Paperclip's Git page. – JJThaeler Apr 01 '14 at 16:48
  • I want you to try as `gem 'paperclip', :git => "git://github.com/thoughtbot/paperclip.git"` in Gemfile and then `bundle install`. Let me know when you finish. – Kirti Thorat Apr 01 '14 at 16:57
  • @JJThaeler Please read my UPDATE 2. I hope you didn't down vote me. – Kirti Thorat Apr 09 '14 at 13:21
  • @KirtiThorat no it's some other issue with Paperclip. They responded and I've done everything listed and still no luck. I will need to reboot everything most likely and try again. – JJThaeler Apr 15 '14 at 13:07
  • @KirtiThorat Thanks for the answer. Forgetting the migration was exactly my issue (upvoted to get you out of the negatives...). – jerhinesmith Jul 09 '14 at 21:14
  • I had the similar issue . But my problem was i generated paper clip using a name called attachment and mistakenly used name avatar in my controller and model ```rails g paperclip document attachment``` – Cliff Feb 06 '18 at 07:29
4

From the error message, file_name is not available in the model to which you're trying to save. I had a similar problem and realized I forgot to run the Paperclip migration:

rails generate paperclip [Model Name] [Attachment] (e.g., rails g paperclip Images image)

If that doesn't work, since the issue it's having is column "file_name", try adding that to the model (e.g. rails g migration addFilenameToImages file_name:string)

This worked for me, so hopefully it helps some of you too!

Jeffrey Bosboom
  • 13,313
  • 16
  • 79
  • 92
Q A
  • 200
  • 2
  • 11
1

Make sure that in paperclip_database:migration you use plural for the new table name and in the paperclip generator you use singular:

rails g paperclip_database:migration cms_article_category cms_article_category_images
rails g paperclip cms_article_category cms_article_category_image

And check the resulting column names in your database In your example the column in the avatar table should be called avatar_file_name

Nino van Hooff
  • 3,677
  • 1
  • 36
  • 52