Reputation: 11
I am having a strange issue with Rails and Paperclip and I am at my wits end trying to solve it.
I have performed all the steps for adding a Paperclip attachment to my model:
FIRST: db updated with "rails g paperclip listing photo" followed by rake db:migrate, schema looks great
create_table "listings", :force => true do |t|
t.text "title"
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"
end
THEN: added 'has_attached_file :photo' to listing.rb model (I have tried the usual proposed solution I have seen, "photo" to my adding "attr_accessible", but this didnt work for be because, as you'll see below, my problem appears to be different)
class Listing < ActiveRecord::Base
has_attached_file :photo
has_many :comments
end
THEN: set up form using multipart and added file_field tag:
<%= form_for(@listing, :html => { :multipart => true }) do |f| %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_area :title %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :photo %><br />
<%= f.file_field :photo %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Yet when I try to create a listing with a photo attached, I get the following in my logs (Note the lack of any photo element in the Parameters hash):
Started POST "/listings" for 127.0.0.1 at Thu Feb 16 16:14:58 -0400 2012
Processing by ListingsController#create as HTML
Parameters: {"commit"=>"Create Listing", "authenticity_token"=>"L6IH7NffyrCbTO0Me9rFb/M3nB2iHyy9BWfh/86H1lQ=", "utf8"=>"\342\234\223", "listing"=>{"title"=>"affefef", "description"=>"awefewfwefwef"}}
SQL (5.4ms) INSERT INTO "listings" ("created_at", "description", "photo_content_type", "photo_file_name", "photo_file_size", "photo_updated_at", "title", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["created_at", Thu, 16 Feb 2012 20:14:58 UTC +00:00], ["description", "awefewfwefwef"], ["photo_content_type", nil], ["photo_file_name", nil], ["photo_file_size", nil], ["photo_updated_at", nil], ["title", "affefef"], ["updated_at", Thu, 16 Feb 2012 20:14:58 UTC +00:00]]
[paperclip] Saving attachments.
Redirected to http://localhost:3000/listings/17
Completed 302 Found in 15ms
I have performed a few checks to attempt to figure this out, such as adding another text_area linked to the photo_content_type directly, and I am able to create a listing with a random string directly assigned to that attribute, so I know I can add form elements other than just "title" and "description" that are in the params of the log above.
It seemed as though this question was identical to mine, because I have the exact same steps and issue, except when I noticed that the log from that post at least has the file in the POST parameters... so I believe that is where my problem lies is that my POST somehow does not get the file_field input in its Params.
Fwiw, I have also created a basic test project that is essentially identical (rails 3.1.3, paperclip 2.6.0, all configs the same as far as i can tell) and it worked just fine, so I know my environment is at least OK for Paperclip.
Let me know if there is anything else useful I can provide that I have forgotten to include.
Thanks!
Shawn
UPDATE:
listings_controller.rb:
class ListingsController < ApplicationController
# GET /listings
# GET /listings.json
def index
@listings = Listing.all
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @listings }
end
end
# GET /listings/1
# GET /listings/1.json
def show
@listing = Listing.find(params[:id])
respond_to do |format|
format.all { render :json => @listing }
end
end
# GET /listings/new
# GET /listings/new.json
def new
@listing = Listing.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @listing }
end
end
# GET /listings/1/edit
def edit
@listing = Listing.find(params[:id])
end
# POST /listings
# POST /listings.json
def create
@listing = Listing.new(params[:listing])
respond_to do |format|
if @listing.save
format.html { redirect_to @listing, :notice => 'Listing was successfully created.' }
format.json { render :json => @listing, :status => :created, :location => @listing }
else
format.html { render :action => "new" }
format.json { render :json => @listing.errors, :status => :unprocessable_entity }
end
end
end
# PUT /listings/1
# PUT /listings/1.json
def update
@listing = Listing.find(params[:id])
respond_to do |format|
if @listing.update_attributes(params[:listing])
format.html { redirect_to @listing, :notice => 'Listing was successfully updated.' }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.json { render :json => @listing.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /listings/1
# DELETE /listings/1.json
def destroy
@listing = Listing.find(params[:id])
@listing.destroy
respond_to do |format|
format.html { redirect_to listings_url }
format.json { head :ok }
end
end
end
UPDATE:
I got to looking at the HTTP Requests for the working and non working versions, and it seems that something on the broken one is causing the browser to interpret the "broken" versions form as application/x-www-form-urlencoded instead of multipart/form-data, despite the rendered forms both appearing to be proper (and the same).
This html:
<html class="ui-mobile"><head><base href="http://localhost:3000/listings/new">
<title>Projectv1</title>
<meta content="authenticity_token" name="csrf-param">
<meta content="L6IH7NffyrCbTO0Me9rFb/M3nB2iHyy9BWfh/86H1lQ=" name="csrf-token">
<body class="ui-mobile-viewport"><div data-role="page" data-url="/listings/new" tabindex="0" class="ui-page ui-body-c ui-page-active" style="min-height: 510px; ">
<h1>New listing</h1>
<form accept-charset="UTF-8" action="/listings" class="new_listing" enctype="multipart/form-data" id="new_listing" method="post">
<div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓">
<input name="authenticity_token" type="hidden" value="L6IH7NffyrCbTO0Me9rFb/M3nB2iHyy9BWfh/86H1lQ="></div>
<div class="field">
<label for="listing_title" class="ui-input-text">Title</label><br>
<textarea cols="40" id="listing_title" name="listing[title]" rows="20" class="ui-input-text ui-body-c ui-corner-all ui-shadow-inset"></textarea>
</div>
<div class="field">
<label for="listing_description" class="ui-input-text">Description</label><br>
<textarea cols="40" id="listing_description" name="listing[description]" rows="20" class="ui-input-text ui-body-c ui-corner-all ui-shadow-inset"></textarea>
</div>
<div class="field">
<label for="listing_photo">Photo</label><br>
<input id="listing_photo" name="listing[photo]" type="file">
</div>
<div class="actions">
<div data-theme="c" class="ui-btn ui-btn-corner-all ui-shadow ui-btn-up-c" aria-disabled="false"><span class="ui-btn-inner ui-btn-corner-all"><span class="ui-btn-text">Create Listing</span></span><input name="commit" type="submit" value="Create Listing" class="ui-btn-hidden" aria-disabled="false"></div>
</div>
</form>
<a href="/listings" class="ui-link">Back</a>
</body></html>
Generates this request:
Request URL:http://localhost:3000/listings
Request Method:POST
Status Code:302 Found
Accept:text/html, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:174
Content-Type:application/x-www-form-urlencoded
Cookie:_jqmoblog_session=BAh7ByIQX2NzcmZfdG9rZW4iMXNJWTZ3aFNqejJKU3lzMHNWY3NpT0VpK3VpMXA3WU0vZ3FqY3l0akR1TFk9Ig9zZXNzaW9uX2lkIiUxOGVmMWExOWEyMTkzY2NkZThiOWJjN2IwMGY4MmJjMA%3D%3D--10e50a0f2b1434f082745442d11009765facf591; _projectv1_session=BAh7ByIQX2NzcmZfdG9rZW4iMUw2SUg3TmZmeXJDYlRPME1lOXJGYi9NM25CMmlIeXk5QldmaC84NkgxbFE9Ig9zZXNzaW9uX2lkIiU1YTE4N2Y3YjQ4YmViYzM4NWE2NjU1NmZkZjEwNWNjMA%3D%3D--f98196fadc924fc31a247d6c12b0e192be2ba11a
Host:localhost:3000
Origin:http://localhost:3000
Referer:http://localhost:3000/listings/new
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.11 Safari/535.19
X-CSRF-Token:L6IH7NffyrCbTO0Me9rFb/M3nB2iHyy9BWfh/86H1lQ=
X-Requested-With:XMLHttpRequest
utf8:✓
authenticity_token:L6IH7NffyrCbTO0Me9rFb/M3nB2iHyy9BWfh/86H1lQ=
listing[title]:efrqwafawef
listing[description]:ewfawefawfa
commit:Create Listing
Cache-Control:no-cache
Connection:Keep-Alive
Content-Length:99
Content-Type:text/html; charset=utf-8
Date:Fri, 17 Feb 2012 04:34:17 GMT
Location:http://localhost:3000/listings/20
Server:WEBrick/1.3.1 (Ruby/1.8.7/2010-01-10)
Set-Cookie:_projectv1_session=BAh7CCIQX2NzcmZfdG9rZW4iMUw2SUg3TmZmeXJDYlRPME1lOXJGYi9NM25CMmlIeXk5QldmaC84NkgxbFE9Ig9zZXNzaW9uX2lkIiU1YTE4N2Y3YjQ4YmViYzM4NWE2NjU1NmZkZjEwNWNjMCIKZmxhc2hvOiVBY3Rpb25EaXNwYXRjaDo6Rmxhc2g6OkZsYXNoSGFzaAk6CUBub3cwOg1AZmxhc2hlc3sGOgtub3RpY2UiJkxpc3Rpbmcgd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLjoMQGNsb3NlZEY6CkB1c2VkbzoIU2V0BjoKQGhhc2h7AA%3D%3D--cee3b017f9321c30c99c844dbe220a2e7c0fe65c; path=/; HttpOnly
X-Runtime:0.053807
X-Ua-Compatible:IE=Edge
Whereas this one:
<html class="ui-mobile landscape">
<title>Jqmoblog</title>
<meta content="sIY6whSjz2JSys0sVcsiOEi+ui1p7YM/gqjcytjDuLY=" name="csrf-token">
<body>
<div data-role="page" id="ui-page-start" class="ui-page ui-body-c ui-page-active">
<div data-role="header" class="ui-bar-a ui-header" role="banner">
<h1 class="ui-title" tabindex="0" role="heading" aria-level="1">New Post</h1>
</div>
<div data-role="content" class="ui-content" role="main">
<form accept-charset="UTF-8" action="/posts" class="new_post" enctype="multipart/form-data" id="new_post" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" class="ui-input-text ui-body-c ui-corner-all ui-shadow-inset"><input name="authenticity_token" type="hidden" value="sIY6whSjz2JSys0sVcsiOEi+ui1p7YM/gqjcytjDuLY=" class="ui-input-text ui-body-c ui-corner-all ui-shadow-inset"></div>
<div class="field">
<label for="post_title" class="ui-input-text">Title</label><br>
<input id="post_title" name="post[title]" size="30" type="text" class="ui-input-text ui-body-c ui-corner-all ui-shadow-inset">
</div>
<div class="field">
<label for="post_body" class="ui-input-text">Body</label><br>
<textarea cols="40" id="post_body" name="post[body]" rows="20" class="ui-input-text ui-body-c ui-corner-all ui-shadow-inset"></textarea>
</div>
<div class="field">
<label for="post_photo" class="ui-input-text">Photo</label><br>
<input id="post_photo" name="post[photo]" type="file" class="ui-input-text ui-body-c ui-corner-all ui-shadow-inset">
</div>
<div class="actions">
<a href="#" role="button" data-theme="c" class="ui-btn ui-btn-corner-all ui-shadow ui-btn-up-c"><span class="ui-btn-inner ui-btn-corner-all"><span class="ui-btn-text">Create Post</span></span></a><input name="commit" type="submit" value="Create Post" class="ui-btn-hidden" tabindex="-1">
</div>
</form>
</div>
</div>
</body></html>
Generates this (properly multipart/form-data):
Request URL:http://localhost:3000/posts
Request Method:POST
Status Code:302 Found
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:19656
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryl9GzwyGxhzaMAAAL
Cookie:_projectv1_session=BAh7CCIQX2NzcmZfdG9rZW4iMUw2SUg3TmZmeXJDYlRPME1lOXJGYi9NM25CMmlIeXk5QldmaC84NkgxbFE9Ig9zZXNzaW9uX2lkIiU1YTE4N2Y3YjQ4YmViYzM4NWE2NjU1NmZkZjEwNWNjMCIKZmxhc2hvOiVBY3Rpb25EaXNwYXRjaDo6Rmxhc2g6OkZsYXNoSGFzaAk6CUBub3cwOg1AZmxhc2hlc3sGOgtub3RpY2UiJkxpc3Rpbmcgd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLjoKQHVzZWRvOghTZXQGOgpAaGFzaHsGOwhUOgxAY2xvc2VkRg%3D%3D--e6b59d98df882703b2b02ddbe9eea4cfd35450b8; _jqmoblog_session=BAh7ByIQX2NzcmZfdG9rZW4iMXNJWTZ3aFNqejJKU3lzMHNWY3NpT0VpK3VpMXA3WU0vZ3FqY3l0akR1TFk9Ig9zZXNzaW9uX2lkIiUxOGVmMWExOWEyMTkzY2NkZThiOWJjN2IwMGY4MmJjMA%3D%3D--10e50a0f2b1434f082745442d11009765facf591
Host:localhost:3000
Origin:http://localhost:3000
Referer:http://localhost:3000/posts/new
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.11 Safari/535.19
------WebKitFormBoundaryl9GzwyGxhzaMAAAL
Content-Disposition: form-data; name="utf8"
✓
------WebKitFormBoundaryl9GzwyGxhzaMAAAL
Content-Disposition: form-data; name="authenticity_token"
sIY6whSjz2JSys0sVcsiOEi+ui1p7YM/gqjcytjDuLY=
------WebKitFormBoundaryl9GzwyGxhzaMAAAL
Content-Disposition: form-data; name="post[title]"
fawfwef
------WebKitFormBoundaryl9GzwyGxhzaMAAAL
Content-Disposition: form-data; name="post[body]"
waefawfwe
------WebKitFormBoundaryl9GzwyGxhzaMAAAL
Content-Disposition: form-data; name="post[photo]"; filename="paul_jones.jpg"
Content-Type: image/jpeg
------WebKitFormBoundaryl9GzwyGxhzaMAAAL
Content-Disposition: form-data; name="commit"
Create Post
------WebKitFormBoundaryl9GzwyGxhzaMAAAL--
Cache-Control:no-cache
Connection:Keep-Alive
Content-Length:95
Content-Type:text/html; charset=utf-8
Date:Fri, 17 Feb 2012 04:38:21 GMT
Location:http://localhost:3000/posts/9
Server:WEBrick/1.3.1 (Ruby/1.8.7/2010-01-10)
Set-Cookie:_jqmoblog_session=BAh7CCIQX2NzcmZfdG9rZW4iMXNJWTZ3aFNqejJKU3lzMHNWY3NpT0VpK3VpMXA3WU0vZ3FqY3l0akR1TFk9Ig9zZXNzaW9uX2lkIiUxOGVmMWExOWEyMTkzY2NkZThiOWJjN2IwMGY4MmJjMCIKZmxhc2hvOiVBY3Rpb25EaXNwYXRjaDo6Rmxhc2g6OkZsYXNoSGFzaAk6CUBub3cwOgxAY2xvc2VkRjoNQGZsYXNoZXN7BjoLbm90aWNlIiNQb3N0IHdhcyBzdWNjZXNzZnVsbHkgY3JlYXRlZC46CkB1c2VkbzoIU2V0BjoKQGhhc2h7AA%3D%3D--ae40706dfb78db19e149df4272663f6c872ee4d6; path=/; HttpOnly
X-Runtime:0.127143
X-Ua-Compatible:IE=Edge
Upvotes: 1
Views: 953
Reputation: 1925
One case in which the uploaded file's parameters would not be part of the params array could be because you are using a component like JQuery Mobile that posts file data via AJAX. You can use an internet browser developer tool to verify the upload data is sent via AJAX (tools like firebug, ie dev tools, chrome inspect elements, etc...) In your view, add this, instead of :html => { :multipart => true } (it is already multipart=true by default in a model generated form)
form_for(@model, html: {data: {ajax: false}})
Hope that helps someone someday! Best of luck Yohann
Upvotes: 4