Sunday 1 September 2013

Some Carrierwave Tip n Tricks

Finally wait is over I mean after nearly a rough patch of virtually no post for an year I back with a post again

As the title suggest it with regards to some tips and tricks that I manage to pull on carrierwave when working on a project

A) Upload Simultaneously to File and S3

I know there are tons of way to do this like upload the file first to server and then using the background process upload it to S3 blah blah .
Even directly upload to S3 is also an options since AMAZON S3 allow CORS

Well all this work great but I kind of not want to do them perhaps, may try some other approach
(Mind you nothing against the other approach mention thus after or already exists)

So what is my approach well basically nothing all you have to do customize your uploader a bit (not heavy customization though )

Consider this is your standard uploader look like  with default storage as :file

class MyUploader < CarrierWave::Uploader::Base
  storage :file
  ... blah ...
  ... blah ... 
  ... blah ... 
end
Now to simultaneously upload it to S3 all you have to do is place this in your uploader.
 version :s3_version do
     storage :fog
     def full_file_name
       super.sub(/s3_version_/,'')
     end
   end
So your uploader finally look like this
class MyUploader < CarrierWave::Uploader::Base
   storage :file
    ... blah ...
    ... blah ...

   version :s3_version do
     storage :fog
     def full_file_name
       super.sub(/s3_version_/,'')
     end
   end
end

That it define a version :s3_version (virtually any name you want) and then use storage as :fog in it (make sure to change the REGULAR EXPRESSION incase you chose a different version name other then s3_version)

Note : Also make sure to add the FOG setting for Carrierwave (S3 is just taken as an example it would work it all storage that fog provide)

Now most of you would argue that if say S3 isn't responding/ something goes wrong in S3 over net, then your local storage goes for a toss and I agree completely with that to so I urge viewer to please take a note of this . Well for me I happy taking that risk on my part . :)


B). Delete the record but don't delete the attachment

Well not all would agree with me on this but there are time when we been ask to delete the uploader record but not delete the file stored :)

There could be many reason like in my case there was a requirement that we need to retain the original copy of the client registered agreement even though the client not longer exists

As said there exists even a dozen tons of ways to achieve this as well but let me show you how I manage to pull off this.

All I did is I overwrite the method remove!  in my uploader and I also define a attr_accessor against my model (i.e attr_accessor :keep_file on my model)

Enough said time for code
class MyUploader < CarrierWave::Uploader::Base 
  def remove!
     unless model.keep_file
       super
     end
  end
end


Now to secure the storage file and only delete the record all I did is set  :keep_file => true and rest is taken care.

What I mean is record are destroyed but not the file from the storage system with this

There is another approach but I now tried and tested it that one would to overwrite the remove? 
method  something like this (Note I haven't tested this )
class MyUploader < CarrierWave::Uploader::Base 
  def remove?
    false
  end
end

C). Custom the CarrierWave Error Message

Ever since I question/answered my own question I'm seeing that I'm getting a lot of traction on it . What I have asked for is -

How to change the Carrierwave error message and set your own ?.

Well clearly the answer for that is define a key/value in your en.yml for desired carrierwave error message and that it

e.g Let say Carrierwave default message on extensions whilelists valdations is this
You are not allowed to upload %{extension} files, allowed types: %{allowed_types}

Now want is to change reason (reason with held with me :) ) . So all I have to do is this

in my en.yml define something like this
en:
  errors:
    messages:
       extension_white_list_error: 'My Custom Message'

A full list of carrierwave key/value pair can be found over here

That it guys hope you liked the tricks and found it useful

Thank You






Friday 23 August 2013

Lesson Learnt about MySQL Datatype

The Content is derived for Rails audiences but it also useful for all those guys who ever had used/currently using  framework supported by a Database Mapper encapsulated in them. 

The post describe how naively we ignore the database ideology and lay all our worries to ActiveRecord and one of this worry is defining Data Type in ActiveRecord . 

All Rails guys would be quite familiar with the following command .
rails g migration add_column_to_some_table some_column:float
rake db:migrate 

Now this create a datatype FLOAT in database (MySQL) .

Now all look fine up till now but there is problem (if your using MySQL database preferably) .

Problem is how MySQL understand FLOAT DataType .

According to  MySQL documentation . MySQL accept the FLOAT datatype definition to look like this .
alter table some_tables change some_column some_column float (7,4) 
I mean float(L,P) .
L => Length of the number 
P => Number of Precision Value 

So from above "7" is length of the number and "4" is max precision so the max number that specify (7,4) criteria is 999.9999 .

Now as usual it not mentioned anywhere in the MySQL documentation what is default format of FLOAT is?
Well, if not specified (because that's what the above migration do,it defines a FLOAT without any precision. A common practice that developer do these days)

So what is the FLOAT format when not specified(e.g above) .

The answer  => Default Precision (6,0) .

Conversion and Rounding Issue.
Real World                    MySQL
511111.1221                   511111
51111.1221                    51111.1
5111.1221                     5111.12
 ... ...                      ... ...
 ... ...                      ... ...
Real World                  MySQL
5111111.12121              5111110
51111111.12121             51111100
511111111.12121            511111100


So friend always, watch out rounding issues.

A Lesson well Learnt .

Thanks 



What did I learn today?

Welcome to the what did I learn today series. The intention of this blog spot is to compose the stuff that I learnt day-to-day basics and jo...