conditional validation: if file upload, then check minimum size - ruby-on-rails-4

I want a validation in my organisations model that runs only, when an image file is selected for upload.
app/models/organisation.rb
class Organisation < ActiveRecord::Base
validates :name, :url, :street, :city, :zipcode, presence: true
validate :validate_minimum_image_size, if: # file is selected for upload
def validate_minimum_image_size
image = MiniMagick::Image.open(picture.path)
unless image[:width] > 300 && image[:height] > 300
errors.add :image, "should be 300px minimum!"
end
end
end
Is there a way to check image size when the image file is selected to upload?

You can provide your own custom method sth like :
validate :validate_minimum_image_size, if: :file_present?
def file_present?
picture ? true : false
end

Related

Rails 4 - Paperclip - Pass image name as method parameter and remove it inside it

I have several paperclip attachments in a Model. I want to pass the name of it as a parameter for a method and then set it to nil.
class Campaign < ActiveRecord::Base
has_attached_file :header_image
has_attached_file :footer_image
end
class CampaignsController < ApplicationController
def remove_image(image_name)
#campaign.image_name = nil # <- I want to do something like this
end
end
How to do something like this? Is there a better way?

Form validation exclusion for a word

I am trying to add a validation to a simple form in a Rails 4.1 project. I need to reject a form submission if a text field contains a forbidden word. My other validations work but not this one. So if the user enters no value or too long of a value it is rejected and the error message is displayed.
I have it setup similarly to the edge guide (http://edgeguides.rubyonrails.org/active_record_validations.html#exclusion) but the form submit still goes through if I enter "My favorite color is red." What should I do differently?
My model:
class ColorEntry < ActiveRecord::Base
validates :body, presence: true
validates :body, length: { maximum: 255 }
validates :body, exclusion: { in: %w(red) }
end
Try to use a regex validation for format with the "without" attribute. So, if it does not match, the form can't be submitted.
validates :body, format: {without: /example/}
Other syntax
validates_format_of :body, without: /example/
More references in:
http://api.rubyonrails.org/classes/ActiveModel/Validations/HelperMethods.html

Omniauth-Twitter - original profile image

I am using Omniauth-Twitter gem to authenticate users and show their profile images. When I attempt to display a full-size user profile image in my users#show view, via link_to method, the image gets resized to 41x41px. Is there any way to get a standard image URL (256x256px)?
My omniauth.rb initializer has the default image size set to original, as follows:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, "...", "..."
{
...
:secure_image_url => 'true',
:image_size => 'original',
...
}
end
and my User model appends the Twitter image URL to a column in the Users table like so:
class User < ActiveRecord::Base
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
...
user.image_url = auth.info.image
...
end
end
end
What I've tried:
Removing :image_size pair from the data hash
Passing width: and height: properties to the link_to
Changing the value of the image_size key to
.extra.raw_info.profile_image_url
The solution I found would probably violate the mighty convention over configuration principle:
remove any calls that determine the image size (i.e. from the URL string by using .gsub! method like so:
"profile_image_path_normal.jpg".gsub!("_normal","") #replaces "_normal" with nothing
Would love to hear other suggestions.

Rails 4, Carrierwave, Jcrop, image upload and resizing

UPDATE
I moved the crop code from the uploader directly to the Notebook Model so that it gets called at least. Now, the image is getting processed. It's getting cropped in fact, to the correct width and height dimensions, but the x and y offsets are wrong. I'm using MiniMagick, not RMagick. Here is my crop_image method:
def crop_image
if crop_x.present?
image.manipulate! do |img|
x = crop_x.to_i
y = crop_y.to_i
w = crop_w.to_i
h = crop_h.to_i
z = "#{w}x#{h}+#{x}+#{y}"
img.resize "600x600"
img.crop(z)
img
end
end
image.resize_to_fill(224, 150)
end
Has something changed in Rails 4 with regards to carrierwave or imagemagick? I copied over code that I had working (in a Rails 3 application) to upload an image, crop it, and save both versions, but I can't get it to work in the Rails 4 app.
Here are the relevant parts:
class Notebook < ActiveRecord::Base
validates :title, :access, presence: true
mount_uploader :image, ImageUploader
belongs_to :user
has_many :invites
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
after_update :crop_image
def notebook_title
title
end
def user_name
user.name
end
def crop_image
image.recreate_versions! if crop_x.present?
end
end
And the recreate_versions! call accesses the image_uploader
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
include Sprockets::Rails::Helper
storage :file
include CarrierWave::MimeTypes
process :set_content_type
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Create different versions of your uploaded files:
version :large do
process resize_to_limit: [600, 600]
end
version :thumb do
process :crop
resize_to_fill(224, 150)
end
def err
raise "error here"
end
def crop
if model.crop_x.present?
resize_to_limit(600, 600)
manipulate! do |img|
x = model.crop_x.to_i
y = model.crop_y.to_i
w = model.crop_w.to_i
h = model.crop_h.to_i
size = w << 'x' << h
offset = '+' << x << '+' << y
img.crop("#{size}#{offset}")
img
end
end
end
end
I'm seeing values for crop_x, crop_y, crop_w, and crop_h. The version :thumb block does not seem to call any process methods. Even if I try to raise an error from inside the version :thumb block, it doesn't work.
If anyone can provide any info that would be great.

Rails 4, not saving #user.save when registering new user

When I try to register an user, it does not give me any error but just cannot save the user.
I don't have attr_accessible. I'm not sure what I am missing. Please help me.
user.rb
class User < ActiveRecord::Base
has_secure_password
validates :email, presence: true,
uniqueness: true,
format: { with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i }
validates :password, presence: true, length: {minimum: 6}
validates :nickname, presence: true, uniqueness: true
end
users_controller.rb
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params) # Not saving #user ...
if #user.save
flash[:success] = "Successfully registered"
redirect_to videos_path
else
flash[:error] = "Cannot create an user, check the input and try again"
render :new
end
end
private
def user_params
params.require(:user).permit(:email, :password, :nickname)
end
end
Log:
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x5OqMgarqMFj17dVSuA8tVueg1dncS3YtkCfMzMpOUE=", "user"=>{"email"=>"example#example.com", "password"=>"[FILTERED]", "nickname"=>"example"}, "commit"=>"Register"}
(0.1ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'example#example.com' LIMIT 1
User Exists (0.1ms) SELECT 1 AS one FROM "users" WHERE "users"."nickname" = 'example' LIMIT 1
(0.1ms) rollback transaction
Regarding our short discussion in the comments, it appears that one or two things are happening to cause #user.save to return false:
One of the validation rules are failing
A callback within your model is returning false, thus halting processing and rolling back the transaction
There are a few quick ways to debug the validations. I figured I could describe them so you could learn a few options.
A. Change the call within the if statement to instead use the bang method of save:
if #user.save!
This will cause the app to raise an exception if validation fails, displaying the validation errors within the browser on your screen. In this particular scenario, you'd want to remember to remove the ! after you're done debugging because you probably don't want the final version of your app doing that.
Or...
B. Within the else statement, add this line:
raise #user.errors.to_yaml
This will display the validation errors within the browser on the screen. Of course, remember to remove this line after you're done debugging.
Or...
C. Within the else statement, add this line and then run the form post:
puts #user.errors.to_yaml
This will display the validation errors within your console. You'll want to remember to remove this line after you're done debugging, but it's "less worse" if you happen to forget because at least the extra info is only output to STDOUT.
You may want to try each of these just to get a little practice and to see what your options are in simple debugging scenarios like this.
High chances that error is in password confirmation. You use has_secure_password from Rails, which automagically handles password confirmation for you. And here is the problem - you don't have it before user creation. Thus just add. For details check out similar question on has_secure_password
And check, that you have password_digest:string in users table :)