Rspec/Paperclip: validation fails even with following documentation - ruby-on-rails

Here is my validation:
describe User
it { should validate_attachment_size(:avatar).less_than(20.megabytes) }
end
Here is my User model:
class User < ActiveRecord::Base
validates_attachment :avatar, :content_type => { :content_type => /image/ }, size: { in: 0..20.megabytes }, allow_blank: true
end
The error I keep getting is:
Failure/Error: it { should validate_attachment_size(:avatar).less_than(20.megabytes) }
Attachment avatar must be between and 20971520 bytes
Not sure why this is failing. Any help is greatly appreciated!

Related

How to move validation for Action Text attachment from javascript to model

We're currently doing this to validate uploads for action text and it's working ok. Is there a way to move this validation to the server, i.e. in course.rb instead of in javascript?
models/course.rb
class Course < ApplicationRecord
has_rich_text :description
has_one :description_text, class_name: 'ActionText::RichText', as: :record
end
javascript/packs/application.js
window.addEventListener("trix-file-accept", function(event) {
const acceptedTypes = ['image/jpeg', 'image/png', 'application/pdf']
if (!acceptedTypes.includes(event.file.type)) {
event.preventDefault()
alert("Attachment types supported are jpeg, png, and pdf")
}
const maxFileSize = 1024 * 1024 // 1MB
if (event.file.size > maxFileSize) {
event.preventDefault()
alert("Attachment size must be less than 1 MB")
}
})
There's a gem for that - https://github.com/igorkasyanchuk/active_storage_validations
You will be able to write a regular-looking validation in your model:
has_one_attached: file
validates :file, attached: true, size: { less_than: 100.megabytes , message: 'too big' }

how to add rspec for paperclip gem validation for images

I have a Post model like this:
class Post < ApplicationRecord
has_attached_file :image,
styles: { large: "500X500",
medium: "300x300>",
thumb: "100x100#" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
end
I am not sure what you really want to write a test for, but you can use Paperclip::Shoulda::Matchers to write simple ones:
describe Post do
# For: `has_attached_file :image`
it { should have_attached_file(:image) }
# For: `validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/`
it { should validate_attachment_content_type(:image).
allowing('image/png', 'image/gif').
rejecting('text/plain', 'nonimage/something') }
end

paperclip resize not working for dynamic columns on attachment model

I have a two columns on my attachment model on which the user sets the dimension to which they want to resize the image.
However, the variables when the resize happens are nil, but set to actual values after the resize happens.
below is the code
has_attached_file :file, :styles => lambda { |a|
{ :logo => ["200x50>",:png],
:user_defined => ["#{a.instance.custom_width}x#{a.instance.custom_height}>",:png] }
}
the custom_width & custom_height are nil when conversion happens however the logo conversion works as expected.
I am using ruby 2.2.4p230 & Rails 4.2.4
below is the full mode code
class Attachment < ActiveRecord::Base
belongs_to :model_one
belongs_to :attachable, polymorphic: true
#has_attached_file :file, styles: { logo: ['200x50>',:png] }
has_attached_file :file, styles: lambda { |attachment| attachment.instance.styles }
def styles
Rails.logger.info self.inspect
Rails.logger.info self.attachable
styles = {}
m = "200x50>"
l = "#{self.custom_width}x#{self.custom_height}>"
styles[:logo] = [m, :png]
styles[:user_defined] = [l, :png]
styles
end
end
Can anyone please help and let me know if i am doing something wrong?

How to upload image in a rails json api using paperclip?

Hi I'm building a json api on rails. I have a model class Product that has a image associated with it.
Here's my Products Controller
def create
params[:product][:image] = parse_image_data(params[:product][:image]) if params[:product][:image]
product = Product.new(product_params)
product.image = params[:product][:image]
if product.save
render json: product, status: 201
else
render json: {error: product.errors}, status: 422
end
end
private
def product_params
params.require(:product).permit(:title,:description,:published,:product_type, :user_id, :image, address_attributes:[:address, :city_id])
end
def parse_image_data(image_data)
#tempfile = Tempfile.new('item_image')
#tempfile.binmode
#tempfile.write Base64.decode64(image_data[:content])
#tempfile.rewind
uploaded_file = ActionDispatch::Http::UploadedFile.new(
tempfile: #tempfile,
filename: image_data[:filename]
)
uploaded_file.content_type = image_data[:content_type]
uploaded_file
end
def clean_tempfile
if #tempfile
#tempfile.close
#tempfile.unlink
end
end
The Product Model :
class Product < ActiveRecord::Base
belongs_to :user
has_one :address
has_attached_file :image, styles: { thumb: ["64x64#", :jpg],
original: ['500x500>', :jpg] },
convert_options: { thumb: "-quality 75 -strip",
original: "-quality 85 -strip" }
validates :title, :description, :user_id, presence: true
validates :product_type, numericality:{:greater_than => 0, :less_than_or_equal_to => 2}, presence: true
accepts_nested_attributes_for :address
validates_attachment :image,
content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] },
size: { in: 0..500.kilobytes }
end
I'm sending the post request using postman with the following request payload :
{
"product": {
"title":"Lumial 940",
"description": "A black coloured phone found in Hudda Metro Station",
"published": "true",
"product_type":"2",
"user_id":"1",
"address_attributes":{
"address": "Flat 16, Sharan Apartments, South City 1",
"city_id": "2"
},
"image":{
"filename": "minka.jpg",
"content": "BASE64 STRING",
"content_type": "image/jpeg"
}
}
}
But while creating, the Product is being created with the image properties but the image_path attribute is saved as null in the database. I can see the image being written in the public directory under my rails application. How can I get to save the image_path as well?
Can someone help me how to solve this?

Paperclip override validates_attachment in subclass

I am trying to override validates_attachment in Subclass but I notice it only works well with Superclass validation; I wonder why my validates_attachment in subclass doesn't work. Has anybody faced this problem? and how have you solved this problem? Here is an example code:
class Superclass
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "28", "4:1" => "50", "5:1" => "40"} }
end
class Subclass < Superclass
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "40", "2:1" => "60"} }
end
I suggest that you should put both the class's fields in different tables. It could be possible that you are getting problems because of that.
However if you really want to have only one table for both the classes then I believe that you could use something like this:
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "40", "2:1" => "60"} }, :unless => Proc.new {|attach| attach.type == "SubClass"}
I assumed that you have a attach_type column but depending on how you are determining whether the attachment type is a SubClass, it is left upto you to change it.
You could also try to remove your validates_attachment from the Subclass and instead try with_options in your model, like the following:
with_options :unless => :attach_type == "SubClass" do |attach|
attach.validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "40", "2:1" => "60"}}
end
This works for me... rails 4
validates :photo, :presence => true,
:attachment_content_type => { :content_type => "image/jpg" },
:attachment_size => { :in => 0..10.kilobytes }
Incase anyone else runs into an issue where they need instance access before they can validate I used the following:
class AttachmentDynamicContentTypeValidator < Paperclip::Validators::AttachmentContentTypeValidator
def validate_each(record, attribute, value)
#record = record
super
end
def allowed_types
#record.my_valid_types_array || ["text/plain"]
end
def check_validity!; end
end
And in the actual asset instance I added the following:
class Asset < ActiveRecord::Base
validates :asset, attachment_dynamic_content_type: :asset_content_type
end
Hope that helps someone.

Resources