Showing posts with label Ruby. Show all posts
Showing posts with label Ruby. Show all posts

Friday, 10 April 2015

Using HTTPProxy in Net/HTTP globally.

There comes a time when you want to Proxy your Net/HTTP request/response in Ruby.

One of the easy ways to do this in NET/HTTP is by passing proxy parameters in '.new'  method (during initialization)

proxy_addr = 'your.proxy.host'
proxy_port = 8080

Net::HTTP.new('example.com', nil, proxy_addr, proxy_port).start { |http|
  # always proxy via your.proxy.addr:8080
}

Obviously, this works but then querying the website using GET or GET BY URI method there is no provision to pass any proxy parameters altogether(at least that's what I found out.)

Thankfully Ruby-2.0+ (not available in lower versions though, can be seen over here) has a feature with which you can provide proxy as your ENV variable (http_proxy environment variable) and ruby take care of the rest.

So, upon setting  http_proxy in ENV I found, BAAM!!!  it worked and it worked globally (i.e it works even on GET and GET BY URL methods mentioned above.)

BTW, I had the following declaration inside my .bash_profile.


export http_proxy= 'http://127.0.0.1:8080'  (8080 is the port where my Squid Proxy is functional)


Thanks




Monday, 16 March 2015

Hack With Rack

Hello everyone, Hope you are having a good day.
Ok, some years ago, one of our clients wanted us to implement Social Network (FB,Twitter,Linkedin) sharing functionality. Knowing all the OAuth implementation that one has to deal with, we decided to use this awesome gem called OmniAuth that does all the heavy lifting tasks of OAuth Authorisation with very basic minimum implementation.
So with OmniAuth we manage to get the work done in time but then we wanted OAuth Authorisation to work with Ajax call as well. I remember going all out crazy (Googling + debugging OmniAuth code) to find a way to do it but honestly we couldn’t find any way do it. (Note: This was some years back I’m not sure about the status as of now.)
So we decide to write our own “Rack Middleware” that tampers with the Omniauth Response and treats the ajax request the way we wanted.
The Middleware

and then we insert the Middleware where we wanted it

Let look at our middleware stack

Yup that's it- a "Hack with Rack" to get a concrete solution for our problem that isn't too fancy but still does the task we needed getting done.

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






Monday, 23 April 2012

What I missing in Rails 2.3+

Well 3.1 and 3.2 is been out for quite a while now so I intend to dedicate this post is for all those fellow coder who still believe or want to maintain there code with rails 2.3+ to let them know that what actually they are missing

If I happen I go about and write the all new feature of rails 3.1 or rails 3.2 then I guess I will run out of word but still I ensure that I cover most important one though

1. Unobtrusive Javascript :
              Before I move ahead and announcement ,Rails 3+ has default javascript framework as jQuery instead of Prototype as opposed to rails 2.3+ and older version (+1 on this) and by adapting HTML standard Rails 3+ encourage developer to write unobtrusive javascript and give them the ability to work seemless of javascript frameworks in our case its jquery(default) so all you need is to install the gem jquery_ujs( you dont have to do this for rails-3.2).If your a prototype support dont get dishearten there is a piece of cake for you too just install the prototype-rails gem and your ready to go

Now all by developer folks would agree with me saying that  back in rails 2.3+ days writing erb code server side would turn up looking one big mess in HTML
here what I meant

a simple delete link in rails 2.3+ would look like this
<%= link_to 'Destroy', user, :confirm => 'Are you sure?',:method => :delete %>
under the hood create such a big mess in HTML

<a href="/users/1" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'FqAHj1L667xA8SmeQjHvVncy8WJz0shaoKjiLHbhQT0='); f.appendChild(s);f.submit(); };return false;">Destroy</a>
same is true if your writing and ajax related code using using any of Rails 2.3+ ajax helper (e.g link_to_remote,remote_form_for etc)

Now with Rails 3+ you can just clean all this mess let me show you how .
link_to_remote is replace  with  normal link_to syntax with once extra parameter remote => true  providing this  help in rails understand to create a link that under hood fire an ajax request (identified by jquery_ujs on click)which is basically achieve by creating a custom data-attribute data-remote => true . same is true with confirm

In Rails 2.3+ a normal link_to_remote would look like this.

<%= link_to_remote 'Edit', :url => edit_user_path(user)  %>
this will produce html on browser like this.
<a href="#" onclick="new Ajax.Request('/users/1/edit', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('FqAHj1L667xA8SmeQjHvVncy8WJz0shaoKjiLHbhQT0=')}); return 
false;">Edit</a>
not so clean let see the same in Rails3+ with slightly different syntax.
<%= link_to 'Edit' ,edit_user_path(user) , :remote => true %>
would produce the below underlying HTML code in browser
<a href="/users/3/edit" data-remote="true">Edit</a>
Totally unobtrusive Javascript 


So now hence forth the both server side and client side code is much cleaner now hooray !!


2. ActiveRelation (AREL - CHAINING QUERY)
       I must admit this the  first time I heard this it just blew me the ActiveRelation original created by and written nkallen before rewritten by many especially one person Aaron Patterson citing performance issue thankfully it done now.
(want to know more about ActiveRelation please go through this )

What ActiveRelation basically mean is back in Rails 2.3+ if you want to retrieve record from a database you basically would do use any of this
Model.find(:all,:conditions => {} )
 e.g (list all user that are admin right in the application)
User.find(:all,:conditions => {:admin => true} )
Now in Rails 3+ you could achieve this using
Model.where('your conidtion')
e.g
User.where("admin =?",true)
Now the basic difference between the above two query interface apart from  syntax is that earlier one (Model.find() ) return you all records  against your query
but the latter(Model.where) one return you with a relation object which is cool
because this mean I can just chaining the query to every relation object returned

like 
Model.where().order().select()
Now the actual query is fired only when you enumerate over your object or  you supply a '.all' syntax to end of Query

like
Model.where().order().select().all
So what Rails 3+ essential does is it kind of lazy load all of records only when you actually need it. Simply Awesome

Here list of method that Rails 3+ ActiveRecord provide
 - where
 - select
 - group
 - order
 - reorder
 - reverse_order
 - limit
 - offset
 - joins
 - includes
 - lock
 - readonly
 - from
 - having
Which such Awesome feature Rails 3+ also has support for old syntax to so as to help migrating Rails 2.3+ application to 3+

Just in inline what used to named_scope in rails-2.3+ is 'scope' in rails 3+ hence worth you like to use named scope something like this
scope :admin , where("admin =?",true)
User.admin

3. Action Dispatcher (New Route API)
   Yes with all the this amazing changes there are changes in Rails 3+ routing too.In Rails 3+ the Routing API is much more cleaner and sound a bit more Rubyish here I will list the difference between rails 2.3+ and newest syntax


i.Now the routes is laid all under your app name
something like
RentHouse::Application.routes.draw do
  ... 
  ...
  ...
end

(RentHouse is your app name)
instead of ActionController in Rails 2.3+

ActionController::Routing::Routes.draw do |map|
  ...
  ...
  ...
end

ii.Get rid of block parameter(map). Now you see map is now more an options in rails3+  

iii. nested resources

 In rails2.3+
 map.resources :products do |products|
  products.resources :comments
  products.resources :sales, :collection => { :recent => :get }
 end
     
Same can be achieve using Rails 3+
  resources :products do
    resources :comments
    resources :sales do
      collection do 
        get 'recent'
      end
    end
  end
  or
 resources :products do
   resources :comments
     resources :sales do
       get 'recent' :as => "collection"  
     end
   end
 end

Sound more rubuies right I dont know about you guys I feel Rails 3+ simple act like DSL where you define Domain logic  

iv . Regular Routes

 Rails 2.3+
map.connect 'product_describe',:controller => "products",:action => "describe" 

 In Rails 3+
match 'product_describe', :to => "products#describe"

Look a bit cleaner right

v. Named Routes 

 In Rails 2.3+  
map.describe 'product_describe',:controller =>"products",:action =>"describe"
In Rails 3+
match 'product_describe', :to => "products#describe", :as => :describe

Now there quite a lot more changes in Routes I recommend refer Rails 3+ routing API for more information

vi. Here an announcement coming
  "Rails has never been so Rack friendly as Rails3+ is"

Now you can just plug and play any of your rack app in Rails3+ and it way to easy and Routes too is no exception (as rails3+ routes embrace so beautifully just like that whole rails)

mount your rack app all you need is point it in your routes
 match '/rack_it_up',:to => RackItUp
(RackItUp is rack app (sinatra,cramp,or anything else)

So Awesome <3 Rails3+


4. ActionMailer API Rewritten.

      This is brand( I mean rewritten) new by Mike Lindsaar I guess we all knew that in Rails 2.3+ ActionMailer use tmail gem well I guess in Rails 3+ it been rewritten with mail gem      

Apart from mail gem ActionMailer has separate directory now for all your mailer code. Which I guess I was missing in Rails 2.3+ where one just would write there mailer code inside model. the syntax too is bit change now here a user_creation_mail

Now in Rails 2.3+ you would have code written like this
class DeliveryMailer
  def user_creation_email(user_created,password)
    subject   "User Registration Mail"
    recipients user_create.email
    from 'myapp@test.com'
    body :user => user,:password => password
  end
end
To sent the mail we would call
DeliveryMailer.deliver_user_creation_email(user,"SECRET")
Same in Rails 3+ with mail gem would be written as
class DeliveryMailer
  def user_creation_email(user_created,password)
    @user     = user_created
    @password = password
    @from     = 'myapp@test.com'
    mail(:to => user_created.email,:subject => "User Registration") 
  end
end
Now to deliver this mail all you need to do is  call
DeliveryMailer.user_creation_email(user,"SECRET").deliver
Kind of look neat isn't it

Note that we are passing object in instance variables so that we can use them in the email template.


5. ActiveModel

        Shout loud if you feel in rails-2.3+ managing tableless model or using some noSQL with model was so much pain

First you need to uncomment -active_record from your environments file asking it(rails) not to be loaded AciveRecord in Rails(really), as if that was not enough.you happen to stumble upon all the errors that you never encounter
(if you want to achieve this in Rails2.3+ here a link .)

Now if you want to associate callbacks or validations with your model. You probably think of writing your own(and there goes DRY ideology) , wasn't there something that has all the underlying ActiveRecord API where all the validation and callbacks would be defined which would help in better managing of noSQL or tableless model easy

Now a step ahead .You think Rails 3+ has it.

ActiveModel is the place where all the validation and callbacks of ActiveRecord are define now we could integrate ActiveModel in your models and you could have all validation and callbacks in a snap.

Great work Guys Love you Rails3+ for this.



6. Faster Development ActiveReload
   I guess this was integrated in Rails 3.2 . How activereload gem created by Robert Pankowecki which basically started as project to speed up development environment quickly became the most downloadable library to speed up your development environment insanely fast close 300% faster . Now the good new is that active_reload in merge in Rails 3.2 here the story you may want read .Written by Robert about how his gem active_reload

As his word  "Die ActiveReload long live Rails "

All Hail Rails


7. Asset Pipeline
    I guess this feature was introduce in Rails 3.1 what it basically means a better management of your assets (images,stylesheets,javascript) for your applications.

As of Rails 3.1 provide you a bunch of assets directory under 'app' ,'lib', 'public', 'vendor' Now you would place any of your assets any where in the assets directory listed under ('app','lib' .. ) and it would be loaded in application .

Also Rails 3.1 has a support for coffeescript and sass default you could write your javascript or stylesheet in coffee or sass and rails would compile the same for you on run time.
(Note that you don't want to do this production as you don't need you asset to compile on every request) 
You could also precompile your assets but I recommend you to do this only on production using rake asset:precompile:all

What basically precompile do is consider that you have a application.js
//= require 'jquery'
//= require 'jquery_ujs'
//= require 'basic'

precompile would basically club all the three file 'jquery,jquery_ujs,basic' and compress to a single with md5 hash of content in filename application[md5hash].js something like this 
application-908e25f4bf641868d8683022a5b62f54.css 

It also create a gzip version of your assets in case if you need to allow web server to render gzip version of your asset to improve transmission

Now back in rails 2.3+ to cache your asset you would do something like this.
<%= javascript_include_tag :application ,:cache => true %>
And rails would create a script tag
<script src=”/javascript/application.js?1335015587” type=”text/javascript” >
(where 1335015587 is the last modified time.)

Now I have read and face many time that the web server dont treat the latter one so gracefully (webserver doesnot treat '?' so gracefully )

great step taken by rails 3 team in fixing this . 

Asset pipeline has also support for preprocessor

which mean you could chain your application.css or application.js with application.css.sass.erb or application.js.coffee.erb
and can write sass or coffee and erb code in css or js and Rails would do all the necessary compiling.

Now this is basically done using Sprockets as it drill down for each set of processors and compile the file with respect to processor (.erb,.coffee)


8. Template Inheritance
     This one I badly needed it I remember how many time I  wanted more level of layouting thankful to Rails  team we have  template inheritance hooked in rails 3+ but I wish rails 2.3 has this although there where gem like rails-template-inheritance to achieve the same.

Here what I meant with Template Inheritance

consider an application where I have login page and internal pages each having different navigation (like About Us,Contact Us, etc) . Now there are several way you can achieve this segregation but using template inheritance you can achieve this by simple define navigation for each controllers in there respective view directory  

e.g  my application layout preview
 <html>
   <head>
      ..
   </head>
 <body>
   <%=  render 'top-navigation' %>
   <%= yield %>
 </body>
</html>
Now we could define top-navigation partials specific to any controller in there respective directory and rails would render it.

e.g
For UserController Rails will first look for top-navigation partial in the current controller view directory(app/views/users over here) if it can find one it will look for the partial in the application directory defined in view.

hence the name template inheritance as just like controllers where all controller inherit from application_controller all view inherit from application

9. Erubius support
  To be fair I was  expecting this I knew sooner or later Rails team will have default erubius support. there are benchmark laid on erubius website that show how fast
erubius is which regard to erb check here Now basically with hardly any noticeable syntactical change you get faster template compiling.If you want to read the path of integration for erubius in rails3+ I must recommend you read this by Yehuda Katz
 

Thanks to Rails team


10. Dependency Management
    Dependency management was and is major headache in rails2.3+ application unless you are using your application with bundler I still remember getting error like

can load activesupport 2.3.5 already activated activesupport 2.3.11 or some other sort now which bundler already hooked in rails 3 I guess my life is more peaceful

now with Rails 3+ all need do is  'bundle install' that it bundle will manage all your dependency for you ( bundler gem is crafted by highly advance ruby programming) It basically achieve this a DFS (depth first server)


There other list of command like bundle pack , bundle list , bundle exec etc I advice to follow bundle website for more on bundler .


11.  Logging Slow Query
        Everyday I used to inspect Rails3+ commit and I used to ask myself what next ,what next. Well we have this amazing framework what next now and I seem to get surprise everytime,this one is no exception reading through rails commit in (Rails3.2) I was made aware that hence forth I can log slow query for my application . Awesome man now I dont need to config my mysql to log one


All you need is new configuration parameter.
config.active_record.auto_explain_threshold_in_seconds

determines what's to be considered a slow query. Setting that to nil disables this feature.

Default are 0.5 in development mode nil in test and production modes

Rails 3.2 supports this feature in SQLite , MYSQL(mysql2 adapter) and PostgresSQL

12 . Simpler Code and Better Documentation

     All of this but still simpler code management and better documentation ( I wont believe you) I guess I would have said the same but when I looked at rails 3+ code I was wrong far more simpler and modular code and way better documentation than rails2.3+.

Love Rails3+  Keep growing 3> 3> 3> 3> 3> 3>

Saturday, 21 April 2012

Deploying Rails App with Passenger and NGINX

All the ROR begineer every wonder about how the so called ROR expert set and deploy there application in no time. Feeling sorry don't be because after this post you dont have too.

First of all you may like to pause a minute or so and decide the which server you want to use (nginx , apache) depending on your need.

We would be using the awesome nginx server for out post but dont worry if you have apache in your stack hooking up the same is not much different from nginx.

You can download nginx from here or build the nginx based upon distributor package

For Ubuntu it fairly straight forward
sudo apt-get install nginx
(Note: please check your distribution provider for downloading)

but I recommend you to download the nginx source code as one can customized the nginx while configure it with passenger.

Phusion Passenger - a.k.a. mod_rails or mod_rack -- makes deployment of Ruby web application, such as those built on revolutionary Ruby on Rails web framework

Next we can confidently go ahead and install the phusion-passenger gem using
gem install passenger
Once passenger install

Now it time to go ahead and install configure your nginx to work with passenger just go ahead and ran the below command on your favorite shell
passenger-install-nginx-module
(if you have source code of nginx point it when asked by passenger during the above process) 

Now passenger will popup a customized configuration depending upon your environment

Here what passenger displayed me.

Please edit your Nginx me configuration file (probably /opt/nginx/conf/nginx.conf ) ,
  http {
    ...
    passenger_root  /usr/lib/ruby/gems/1.8/gems/passenger-3.0.11;
    passenger_ruby /usr/lib/ruby1.8;
    ...
   }
   server {
     listen 80;
     server_name www.yourhost.com;
     root /somewhere/public;   # <--- be sure to point to 'public'!
     passenger_enabled on;
   }
Copy the above content in your nginx.config
(dont worry if your unaware where is your nginx.conf file located passenger will come to rescue in that too)
 as it would be required you to set up your application now replace 'somewhere' from the above with absolute path for your application

Here how the final configuration look like
worker_processes  1;
events {
  worker_connections  1024;
}

http {
  passenger_root /usr/lib/ruby/gems/1.8/gems/passenger-3.0.11;
  passenger_ruby /usr/bin/ruby1.8;
  include       mime.types;
  default_type  application/octet-stream;
  sendfile        on;
  keepalive_timeout  65;
  server {
    listen       80;
    server_name  myapplication.com;
    root /home/root/application/public;
    passenger_use_global_queue on;
    passenger_enabled on;
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   html;
    }
  } 
}
Set you Database environment and restart the nginx server
/etc/init.d/nginx restart
(you might want to run this as sudo)

Voila, that it congratulation you have successfully deployed your rails application

Go ahead pat yourself in back for this. :) :) :)

Now enter your application url in your favourite browser you should find it working.
If you can't find it or you land up in error page check nginx error.log
(can be found in nginx.log file) or your application log file for more information it could probably
because you would be missing certain gem or you just missed something from the above list

Hope it help you in someway or other.

Thanks You.

Friday, 20 April 2012

process => process in CarrierWave

Well this one is for all those who ever used CarrierWave for uploading there files(no matter which files). Now how many of us had actually extended Carrierwave to process a file (i.e writing you own processing for the file e.g In term of image reducing or increasing the quality of image)

I happen to stumble upon this as all I want was to process a csv file which is suppose to be stored in Amazon S3(on upload) using CarrierWave .

Now the aim was to extract all the information from the CSV (sound simple right ) . Yes it is but I resist the thought of putting the file in Amazon S3 server(first) and then downloading the file and to my server and then extract the data from the CSV file and dump it into database. I want it to be more real time(since the file are small size file) I want user to know that the data in CSV is proper or not and can or cannot data in the CSV can be dumped into database citing validations.

So I realized back when I used to consider PaperClip as my first options, paperclip used to provide me options for processing the file here the link if you want to do it for paperclip Good Luck.

Yes I knew now I have to achieve something of this sort ,but how

Well looking at the uploader file generated by CarrierWave I found out that there is process method ,ok now what how do you apply it.
Inspecting the CarrierWave source code ( for default resize process ) I found out that all you need is to define a method wrapped inside a module .

Now it got it.

So to define a custom processing all you need is to define method wrapped in module and include that module in CarrierWave and pass your process method as an argument to CarrierWave process method define in uploader file
Here how I achieve this.
Inside CarrierWave Uploader
class AssetUploader < CarrierWave::Uploader::Base
   include CarrierWave::CSVProcessor
   process :process_csv
end

That it that all you need to do to define your own file processing.
Just go ahead an define your process_csv method inside module define in file inside config/initializers Voila mission accomplished.
Here how I did it (my file config/initializers/csv_processor.rb)
module CarrierWave
  module CSVProcessor
    def process_csv
      ....
      ....
      ....
    end
  end
end
Go hack now with CarrierWave.

By the way if you want to explore the thought of providing custom error message for CarrierWave here a link that you might want to look at

Hope that it help you in someway or other

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...