I'm using Paperclip in a gem I built for a specific use case. My gem creates an interface for non-programmers to create and edit forms and then allows users to answer those forms.
I want to use Paperclip in order to provide a "File Upload" input type for questions, so my forms are more versatile. However, this means that I need to use the file_field_tag method to display the file input and I need to manually save whatever information is submitted through that input into the appropriate model object. Currently I'm sending the information through with the name question_1 and then trying to pull the uploaded data out with params["question_1"].
My code looks like this:
answer.update_attributes(upload: params["question_1"])
But I'm getting a No handler found for <image_name> error and I can't figure out what I'm doing wrong. I thought Paperclip handles everything after I pass it the data from a file_field?
Solution:
My form looked like this: <%= form_for #answer_set, multipart: true do %> when it should have looked like this: <%= form_for #answer_set, html: { multipart: true } do %>.
I use
has_attached_file :image
validates_attachment_presence :image
validates_attachment_content_type :image, :content_type => ['image/jpeg', 'image/png', 'image/jpg', 'image/pjeg']
and then:
#upload = Upload.find(params[:id])
#upload.update_attributes(params[:upload])
config/environment.rb
Rails::Initializer.run do |config|
config.gem "paperclip", version: "~> 2.7"
end
This thread also suggests checking the multi-part on the form
https://stackoverflow.com/a/10076046/1354978
answer_form_for #upload, :html => {:multipart => true} do |f|
There are also other possible solutions on that page.
Related
I'm building a simple app with standard User model that has_one Profile model. I would like the profiles table to have a column for an image attribute. Therefore, I followed RailsCast #253 titled CarrierWave File Uploads. All is going well until I try to resize an image that has been uploaded. This requires the installation of ImageMagick & RMagick which took an entire day of searching to get done. However, I think I finally got it right and successfully installed rmagick version 2.13.2 (as verified by running "gem list").
But not so fast...now when I try to render the form to create a new profile, I get the following error:
NoMethodError in Profiles#new
undefined method `model_name' for NilClass:Class
FYI, this form was working fine until I un-commented "include CarrierWave::RMagick" in my ImageUploader (which I'm suppose to do if I want to use RMagick methods for image re-sizing).
Any thoughts on how to fix this?
My version info (I used RailsInstaller for Windows to get up & running)
Rails 3.2.13
Ruby 1.9.3p392 [i386-minw32]
ImageMagick 6.8.5-Q16
rmagick 2.13.2
Gemfile
gem 'rmagick'
gem 'carrierwave'
Models
class User < ActiveRecord::Base
has_one :profile
class Profile < ActiveRecord::Base
attr_accessbile :image
belongs_to :user
mount_uploader :image, ImageUploader
ImageUploader
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
ProfilesController
def new
#profile = current_user.build_profile
end
views/profiles/new.html.erb
<%= form_for #profile, :html => {:multipart => true} do |f| %>
<%= f.file_field :image %>
<%= f.submit "Create my profile" %>
<% end %>
Just replace this line
<%= form_for #profile, :html => {:multipart => true} do |f| %>
by
<%= form_for #instructor_profile, :html => {:multipart => true} do |f| %>
Issue is really with form_for not with RMagick, you have defined #instructor_profile in controller but using #profile in view. Make sure that there will be single space between form_for and #instructor_profile
iam using rails with formtastic for my admin backend. i want to be able to upload an image to my recordset, and i try to use paperclip to to that.
when i edit a recordset, the upload of the image works just fine. when i try to CREATE a NEW recordset, paperclip seems to assign the ID 0 for that image in my upload path!
#expected path for new image:
/public/logos/2342/some_image.png
#and thats what i get when i create my new record-set:
/public/logos/0/some_image.png
i tried to add attr_accessible to my model
attr_accessible :logo_file_name, :logo_content_type, :logo_file_size, :logo_updated_at
but that throws me an sql-error
Column 'logo_file_size' cannot be null
EDIT: solved the mysql error when i add attr_accessible. i just allowed the logo_file_size to be null. but the id=0 problem still exists...
my code:
MODEL:
has_attached_file :logo,
:url => "/:class/:attachment/:id/:basename.:extension",
:styles => { :original => ["150x150>", :png] }
VIEW:
<%= f.inputs do %>
<%= f.input :name %>
<%= f.input :logo, :as => :file %>
<%= f.input :link, :as => :url %>
<%= f.input :published, :published => 'Veröffentlicht' %>
<% end %>
CONTROLLER:
def create
Article.create(params[:article])
end
my datebase has these 4 colums in Article-Table:
logo_file_name
logo_content_type
logo_file_size
logo_updated_at
iam using rails 3.1.1, formtastic 1.2.4, paperclip 2.4.5
thanks a lot for your help!!!
i know its a bit late, but i found the problem and will share the answer for everyone with the same problem.
problem was mysql, upgraded to mysql2 gem, and everything worked as expected
in a current Rails 3.0.9 app of mine I had a few .js.erb templates that were using view_context in them so I could call fields_for on it during a ajax request. This was letting me build some nested attribute form fields via ajax. But upon upgrading to Rails 3.1 I'm getting the follow error:
ActionView::Template::Error (undefined local variable or method `view_context' for #<#:0x1057b9f70>):
Was this removed/deprecated recently? Is there another way I can build nested fields_for inputs without having the parent FormBuilder handy? It seems view_context is still available in the controller, but I was hoping to keep this markup generation in the View layer.
My .js.erb template looked like this
<% meal_item_fields = view_context.fields_for :meal_items, Meal.new.meal_items.new, :child_index => "new_meal_items" do |f|
render :partial => 'meal_items/meal_item_fields', :locals => {:meal_item_form => f}
end
%>
$("#meal-items").append("<%= escape_javascript(meal_item_fields) %>");
According to api docs it is deprecated in >= 3. Source of 3.0.9 returned self for view_context. I think if you were to try without view_context it would just work.
<% meal_item_fields = fields_for :meal_items, Meal.new.meal_items.new, :child_index => "new_meal_items" do |f|
render :partial => 'meal_items/meal_item_fields', :locals => {:meal_item_form => f}
end %>
$("#meal-items").append("<%= escape_javascript(meal_item_fields) %>");
You might want to add helper_method :view_context in your controller.
In my config/routes.rb I have:
post "portal_plan_document/update"
rake routes confirms this:
$ rake routes
portal_plan_document_update POST /portal_plan_document/update(.:format) {:controller=>"portal_plan_document", :action=>"update"}
....
In my code I have:
<%= form_for #plan_doc,
:url => portal_plan_document_update_path,
:method => "POST", :remote => true do |f| %>
In my log file I see:
Started POST "/portal_plan_document/update" for 127.0.0.1 at 2011-03-31 18:04:37 -0400
ActionController::RoutingError (No route matches "/portal_plan_document/update"):
I am lost as what to do from here. Any help would be greatly appreciated!
I should state I am using Ruby 1.9.2 and Rails 3.0.5. Oh, I have restarted the server (WebBrick w/rails server) after updating routes.rb.
Jeremy
Figured it out! :)
if you have a non-empty object, rails assumes you want to update that object. i.e., use a 'PUT' instead of a 'POST'
to accomplish 'PUTs', rails will put a hidden input in the form, with "_method" = "put". so, it LOOKS like it's a POST, but rails is treating it as a PUT.
if you actually want to just update an object (what it looks like you're doing), a PUT is better, and you should just switch your routes over to PUT.
if (like I was), you're doing something that really requires a POST (i.e., it can't be sent more than once safely), you can write your form_for like this:
<%= form_for #plan_doc,
:url => portal_plan_document_update_path,
:html=>{:method => "POST"}, :remote => true do |f| %>
to confirm, look at the generated HTML source, and make sure the hidden "_method" field is not set to "put"
Try using that instead please :
:method => :post
If this does not still work, please lose the remote attribute and give it a try. Does it work without it ?
I had the same problem while upgrading a simple app from Rails 2 to Rails 3.
As you may guess I was updating all "remote_form_for(#item) (..)" helpers to "form_for :item remote => true (..)" syntax.
In my case this code from a items/_new.html.erb partial:
<%= form_for :item, :remote => true do |f| %>
<!--FIELDS-->
<% end %>
Gave me this error:
Started POST "/items/new" for 127.0.0.1 at Fri Aug 12 18:19:23
+0200 2011
ActionController::RoutingError (No route matches "/items/new")
As you can notice the method was a correct "POST", not a "PUT". The problem lied in the routing... I don't know why but when a remote POST method is sent by a partial, Rails routes the POST request to "/items/new" instead of "/items" route. Even if the purpose is to create a new "item" so the POST request should be correctly (and RESTfully) routed to "/items".
This code, with explicit action and controller, solved the problem:
<%= form_for :item, :remote => true, :url => { :controller => "items", :action => "create" } do |f| %>
<!--FIELDS-->
<% end %>
I have worked out how to disable the authenticity_token in the controller but rails still creates the field in the forms. How do i turn this off as the server i am posting the form to needs a very specific set of field names.
In rails after 3.2.x you can pass a parameter into the form generator as suggested in another answer:
form_for #invoice, :url => external_url, :authenticity_token => false do |f|
...
<% end %>
In any rails version you can disable globally in config/application.rb, as in another answer:
config.action_controller.allow_forgery_protection = false
In rails 3.0.x you can disable on a page load basis in the controller by overriding the following method. Unfortunately, there seems to be no way to do this at the form level.
protected
def protect_against_forgery?
if ...
# results in the meta tag being ommitted and no forms having authenticity token
return false
else
# default implementation based on global config
return allow_forgery_protection
end
end
To disable it across your application, you can add this line to your config/application.rb:
config.action_controller.allow_forgery_protection = false
For external urls you can turn this of per form as follows:
<%= form_for #invoice, :url => external_url, :authenticity_token => false do |f|
...
<% end %>
Source: http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for