rails 3.2 skip paperclip attachment presence validation on edit action - ruby-on-rails

I am new to Rails and i'm working on my first rails application that uses paperclip for attachments and i'm validating the presence of attachment using validates_attachment :avatar, presence: true which is working perfectly well on create action, but when a user is editing his account settings and doesn't upload a new avatar, there is an error for not having avatar uploaded but i want to skip that validation on edit and only validate on edit if user uploads a new one to replace existing one.
i also have
validates_format_of :avatar, :with => %r{\.(jpg|jpeg|gif|png)$}i,:unless => Proc.new {|m| m[:avatar].nil?}, :message => "Please upload files with the following extensions only
to check format only if present but doesn't seem to be working either
your help would be very much appreciated.
thanks

Use on option.
validates_format_of :avatar ... , :on => :create
http://guides.rubyonrails.org/v2.3.11/activerecord_validations_callbacks.html#on

Related

Validations on money-rails gem

I have money-rails gem installed and it's working flawlessly. However, there are no validations on money objects when I create a new model record. If I try to input letters into the money field, the form submission is successful, it just sets the value to 0. How do I get those validations working? I have no code for the actual validation, seeing as money-rails on github states that it has validations included, but I have tried validates_numericality_of to no avail.
EDIT
Yes I have read the docs extensively, and tried the validation option suggested on Github.
I have this example hope it could help you
monetize :price_cents, :numericality => {:greater_than => 0, :less_than => 10}
validates :price, :format => { :with => /\A\d+(?:\.\d{0,2})?\z/ }
just like this one of them (monetize validation) will validate the numericality stuff and the other one will validate the format.

How to customise devise views in rails 3.2 to include only some elements in the sign up form

I am a rails newbie and I have started hacking together a web app.
I used devise to set up user registrations and also generated the devise views templates.
I added custom models in there - username, first name, surname etc. I then added them in the attr_accessor in user.rb etc. and validates for the presence of these details
I thought of adding these elements in the edit registration form which worked successfully.
On the signup page - the code asks only for email, password, confirm password (as is set as default by devise).
If i now try and register as a new user (after all these steps), i get an error saying that First name cannot be empty, surname cannot be empty etc.
How can i exclude these from the sign up yet keep them active in the user profile edit?
I hope I'm making sense.thanks for your help in advance
If I understand correctly, during signup/registration you want to only ask for email and password, excluding the other User model attributes (first name, surname) from that form. However you also want to later have these other attributes validated when the user edits their profile.
So since you are validating for the presence of these extra attributes which are not provided when the signup form is submitted, the attempt to create a new user record simply fails to create at validation.
Try the :on => :update validation option to specify that certain fields should only be validated when later updated, rather than the default which is to validate any time a record is saved. Like this:
class User < ActiveRecord::Base
validates :email, :presence => true
validates :firstname, :presence => true, :on => :update
validates :surname, :presence => true, :on => :update
...
end
See http://guides.rubyonrails.org/active_record_validations_callbacks.html#on
you can go into your views > devise folder and create a registrations folder if its not there and make a new.html.erb
have a look at the file that you find under the link:
https://github.com/plataformatec/devise/blob/master/app/views/devise/registrations/new.html.erb
copy it to your new file and customize it as you want... it should overwrite the devise default view.

Conditional Validation with Paperclip difficult

I have an "item", which goes through a multi-page creation process. Images are uploaded at step five, and I keep track of the steps by using the attribute "complete". When validating whether an image is attached with paperclip, I get problems using the code below:
validates_attachment_presence :pic1, :if => Proc.new { |u| u.complete == "step5"}
It seems that I can't access the "complete" attribute, as the active-record object seems to be the paperclip image. Is there a way for me to check at which point in the process I am and validate conditionally?
Thanks,
Michael
How about
validates_attachment_presence :pic1, :if => 'complete == "setp5"?'
or
validates_attachment_presence :pic1, :if => :is_step5?
def is_step5?
self.complete == "step5"
end

Smarter paperclip validations

I'm using paperclip in a rails app and have the following three validations in my model
validates_attachment_presence :photo
validates_attachment_size :photo, :less_than=>1.megabyte
validates_attachment_content_type :photo, :content_type=>['image/jpeg', 'image/png', 'image/gif']
If the user forgets to add an attachment, all three validations fail and thus, the user is presented with the following three errors:
# Photo file name must be set.
# Photo file size file size must be between 0 and 1048576 bytes.
# Photo content type is not included in the list
I think it would be best to just show the first error in this instance since the other two errors are purely consequential... I would prefer the user to only ever see the second two errors if an attachment has been added but doesn't meet the validation criteria.
I'm certain there is no pre-baked validation that does this sort of thing and from reading the code in vendor/plugins/paperclip/lib/paperclip.rb I see that the validates_attachment_size method supports the :unless parameter as shown:
def validates_attachment_presence name, options = {}
message = options[:message] || "must be set."
validates_presence_of :"#{name}_file_name",
:message => message,
:if => options[:if],
:unless => options[:unless]
end
So, I was thinking that I could do something like the following:
validates_attachment_size :photo, :less_than=>1.megabyte, :unless=> :photo.blank
But that breaks the app. Anyone have any experience of doing this sort of thing? Would be a nice contribution to the paperclip source code.
EDIT:
I've tried using this:
validates_attachment_size :photo, :less_than=>1.megabyte,
:unless=> Proc.new { |image| image[:photo].nil? }
It doesn't quite work though as I've just managed to upload a 5mb mp3 with this validation in place. But it's promising as the error message doesn't appear when the user has not attached a photo.
validates_attachment_size :photo, :less_than => 1.megabyte,
:unless => Proc.new { |imports| imports.photo_file_name.blank? }
I think you can do it other way. Don't mess with validations. You probably have something like this in your form:
<%= f.error_messages %>
You can remove it and write your own helper to display error messages. Errors are stored in hash:
#photo.errors
Or if you want to get to them through form builder:
f.object.errors

Ruby on Rails ActiveRecord conditional validation (and more..)

I have a Product model which validates multiple attributes (including a Paperclip image attachment) like so:
validates_presence_of :name
validates_format_of :name, :with => /^([a-zA-Z0-9\ \-]{3,128})$/i
...
has_attached_file :image
validates_attachment_presence :image
validates_attachment_content_type :image, :content_type => ["image/jpeg", "image/png", "image/gif"]
Everything is working fine. What I want now is to make an (unobtrusive) hidden iframe in-place upload script using javascript. My problem is that I cannot just upload the image without the rest of the data, because it will fail validation (no name present) and also I cannot send the rest of the form without the image (same thing, fails validation).
So basically what I need (and don't know how to achieve) is to conditionally apply the model validations according to what the action is currently in progress (uploading the image or editing other data).
I hope I was clear enough. Any help is appreciated. Thanks.
Railscasts have a nice video screencast about conditional validations.
I hate having to wade through a video just to get a simple answer. In fact, I think that a blog entry is superior to a simple tutorial video simply for the fact that it is searchable. Here is a simple case in plain text for anyone else looking:
To validate the presence of password only for the create action, do this:
validates_presence_of :password, :on => :create
A comment for Peter D.
Thank you very much. I'm unable to watch that screen cast presently (though I plan to) and was looking for a speedy, brief answer.
Incorporated your suggestion into a model I have and it's working perfectly. (Though I suspect at some point I'm going to need validation on update when passwords are being changed. I'll take it as "technical debt" now though, in order to move on.)
The bit I added:
validates :password, :presence => true, :confirmation => true, :on => :create

Resources