Ruby Screenshot Website Capture – Screencap, Phantomjs

This tutorial will discuss various tools for Ruby Screenshot capture such as

  • Phantomjs (Command-line)
  • Screencap (Ruby gem)

Objective

You need to capture screenshot of a particular web page and you want to do that programmatically by just passing an url then you can use of the gems that I have listed above. After reading this article, you will be able to select an option to use for your needs.

1. Phantomjs

Install phantomjs (If not Installed)

If you're using brew, then -

brew install phantomjs

command will help you install phantomjs on your machine

Installing on CentOS

cd ~
wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-i686.tar.bz2
bunzip2 phantomjs*.tar.bz2
tar xvf phantomjs*.tar
sudo cp phantomjs*/bin/phantomjs /usr/bin/phantomjs
phantomjs -v

If this still gives error of fontconfig/freetype, then try installing using command -

sudo yum install fontconfig freetype libfreetype.so.6 libfontconfig.so.1 libstdc++.so.6
phantomjs -v
2.0.0

This should list the installed version of phantomjs.

Usage

It's fairly easy to capture screenshots using phantomjs. Following code will help you-
Steps
1) Create a .js file with code to capture screenshots - let's say rubyinrails-snapshot.js

var page = require('webpage').create();
page.open('http://rubyinrails.com/', function() {
  page.render('screenshot-rubyinrails-com.png');
  phantom.exit();
});

2) Run the js code as,

rubyinrails-snapshot.js

This code will capture and save screenshots by file name screenshot-rubyinrails-com.png

Screen Capture using Phantomjs command line - This article shows how to capture screenshots with phantomjs in detail

2. Screencap - a Ruby Screenshot capturing gem

  • This is a ruby gem developed on top of phantomjs.
    You need to have phantomjs installed on your machine to capture screenshots with this gem.
  • Source - Screencap Github Source

Installation

  • Install gem by -
    gem install screencap

    This command will install screencap on your machine

  • If you need to use gem from your Rails application then you need to add it to the Gemfile
    gem 'screencap'

    After adding to Gemfile, bundle

    bundle

    This command will ensure availability of your gem your Rails application

Usage

Using screencap gem to capture screenshots is fairly easy. The following code will help you capturing screenshots with ruby -

require 'screencap'
fetcher_object = Screencap::Fetcher.new('http://rubyinrails.com')
screenshot = fetcher_object.fetch

The fetch method supports various options as given below -

  screenshot = fetcher_object.fetch(
    output: '~/some-directory/file-name.png',
    # optional parameters:
    div: '.header', # CSS selector
    width: 1024, # Width of Screenshot - Viewport
    height: 768, # Height of Screenshot - Viewport
    top: 0, left: 0, width: 100, height: 100 # Area to capture screenshot of
  )

Hope, this tutorial helps you to capture screenshots with Ruby. Please feel free to comment down below.

Ruby Flay Gem – DRY code base

Tutorial will discuss Ruby Flay gem used to DRY up Ruby/Rails application. Flay gem enforces Best practices to be followed while coding with Ruby and Rails

Flay gem

Source: Flay on Github
When to Use? - To make your codebase more DRY!

Usage:

1) Install gem by -

gem install flay

2) Process your files.

flay

This command will process ruby/erb (.rb/.erb) files in current directory. You can also run as,

flay app/models

Above command will process all the files in the app/models directory.

3) Output
The flay command will give output -

1) IDENTICAL code found in :resbody (mass*5 = 600)
  app/models/user.rb:252
  app/models/user.rb:563
  app/models/news.rb:95
  app/models/news.rb:326
  app/models/news.rb:1211

2) IDENTICAL code found in :defn (mass*2 = 340)
  app/models/image.rb:223
  app/models/image.rb:236

Above output shows where the codebase has duplication with filename and line number to check for the same.
The gem scans the files for structural similarities. This is useful for making your codebase more DRY (Don't Repeat Yourself)

How to Refactor?

When you check out the file and the line number pointed out by Flay gem you will realize the similarities and you would want to refactor it.

Listing down some of the techniques -

1) Refactor code pointed by Flay to a method.
2) Call the method from all the places pointed out by Flay.
3) Check whether you can create a module out of similar code. It would be useful in future as well.

Points to Remember

- The Flay gives score after scanning which is an integer value.
- Lower the Flay score, more DRY is your codebase
- Try optimizing to decrease Flay (Badness) score

Integrating with VIM

Flay gem has inspired integration with editor such as emacs, textmate, vim. You can integrate with VIM by following instructions at Vim Flay on Github

Resque Setup Development Mode

This tutorial will guide you setting up Resque locally in development mode with Multiple workers and how to use with Rails application to process background jobs.

What is Resque?

You might want to know what is Resque before we begin with commands/flow to set it up locally.

It uses Redis as backend, thus you need to understand Redis architecture to know how resque-workers process background jobs.

Steps
1. Install Redis

curl -O http://download.redis.io/redis-stable.tar.gz
tar -xvzf redis-stable.tar.gz 
rm redis-stable.tar.gz 
cd redis-stable 
make 
sudo make install

This is fine guide to help installing Redis

2. Start Redis server

redis-server start

This will start redis server for you and listen on port 6379

3. Create setup.rb initializers file

uri = URI.parse('redis://localhost:6379/')
Resque.redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password, :thread_safe => true)
Resque.redis.namespace = "redis namespace for your app"

This will connect to redis server which was listening on port 6379

4. Start resque workers

rake resque:work QUEUE=* COUNT=3

This will start 3 workers and will process jobs placed on any queue from your Rails application

Now whenever you enqueue jobs, these workers will process jobs in the background and you can see the logs for the same as well.

Let us know through comments if you face any difficulty setting up in development environment.

Memoization in Ruby

This tutorial will help you understanding Memoization pattern in Ruby. Memoization is different from Lazy Initialization. Rails had Memoize to support memoization pattern which will be discussed as well.

What is Memoization?

Memoization can be used to initialize a variable and store it with the result of some computation that is expected to give same result if computed again. Then the variable is used to return result instead of doing the computation again when needed again.
E.g.

def user_score
  @user_score ||= # some complex calculation for user score
end

The method user_score calculates score based on some complex calculation and stores it in the instance variable @user_score. When code/flow needs value of user_score again then if value @user_score is set then it is returned instead of computing again.
Above statement can also be written as,

@user_score = @user_score || # some complex calculation for user score

This is simplified version.

When to use Memoization

1. When you have complex calculation that is supposed to give same result on multiple calls

2. When you have database query with same parameters for a instance
e.g.

def user_score
  @user_score ||= User.where(name: 'Sam').first.try(:name)
end

If you need user Sam's score then you can calculate and store it. When you need again then you can just return it from the instance variable.

3. When you have a method that is giving same result over multiple calls but you need to call it multiple times

What about nil, false?

Memoization technique discussed above does not work with nil, false values. Let us see why,

@variable ||= false # suppose calculation value is false

which simplifies as

@variable = @variable || false

As @variable had false value it will again go and evaluate for the OR part of condition which will come out false again.
Same will happen in case of nil as well.
Thus, over multiple calls Memoization will not work if value comes out to be nil, or false.

Solution to nil, false scenario for Memoization

def variable
  @variable = false unless  instance_variable_defined? :@variable
  @variable
end

This will not perform calculation which returns result false/nil if the @variable value is already defined. Thus, this solution holds the memoization pattern.

Confused with Lazy Initialization?

What is Lazy initialization?

Lazy initialization is delaying intialization of the object/entity until the need of it for first time.

class User
  def initialize
    @user_score = # same complex caluclation for user score
  end
end

This is example of Not Using Lazy Initialization. @user_score is calculation at the construction time.

class User
  def initialize
  end

  def user_score
    @user_score ||= # same complex caluclation for user score
  end
end

This is the example of lazy intialization in above context. This is use of Memoization in combination with Lazy intialization.

Does Rails support Memoization?

Rails had support for Memoize through ActiveSupport::Memoizable. Memoizable is deprecated from Rails.
We will not go in deep understanding Memoize from Rails as it has been deprecated.
Check this commit as to why Memoizable support has been deprecated.

References

Memoization
Lazy Initialization

Feel free to comment if you have any doubts/suggestions.

Integrate ActiveAdmin with Rails

This tutorial will help you integrating ActiveAdmin with Rails 4+ project. ActiveAdmin is open source administrative framework for Ruby on Rails.

Source: Github Source
Website: ActiveAdmin Website

What is ActiveAdmin?

As described ActiveAdmin is open source administrative framework that can be used with Rails framework. ActiveAdmin is helpful for content management by creating admin users. And giving them access to features to access, modify records. It also gives features to search and sort over database records.

Why ActiveAdmin?

If you are going to create a new web application using Rails framework, and you want to design admin side for the application. Then, ActiveAdmin does exactly the same thing. It gives many features out of the box for you application.

How to Integrate with Rails?

1. Add to Gemfile
gem 'activeadmin', github: 'activeadmin'

Adding activeadmin to Gemfile tells Rails project to use this gem (library) for your project.

2. Bundle
bundle install

This will install activeadmin gem on your machine if not already installed. And it will be ready for use with current Rails application

3. Install defaults for Application
rails generate active_admin:install

This will create initializers and app/admin directory as well. This folder contains configuration files that get used by activeadmin. This also sets up routing for you.
It is advised to use device for user management. ActiveAdmin also relies on device gem for admin user management. If you have not added device in your gemfile then it will ask you to add device gem to your Rails application.

4. Migration
rake db:migrate

ActiveAdmin creates Admin user to begin with. rake db:migrate creates the tables needed for activeadmin to function.

5. Test

Migration also creates a dummy admin user to begin with.
Email: admin@example.com
Password: password
You can test if admin framework is properly integrated from url:
http://127.0.0.1:3000/admin
Use the credentials give above to enter.

6. Register a model

You can register your model to be used with activeadmin by following command:

rails generate active_admin:resource

e.g.

rails generate active_admin:resource Gadget

This will integrate the Gadget model with activeadmin and it will start showing up in admin dashboard, where you can search, edit, update.

7. CRUD with activeadmin

ActiveAdmin provides a way to create new records for registered models. When you open particular models page, it shows records in the table and gives filtering functionality. It also provides create, update features.
You can test this with the existing model that gets created during installation:
http://localhost:3000/admin/admin_users
This will show 1 record that you are logged in with. Option to view, edit and delete is provided.

8. Setting attributes for update

You need to set attributes to be permitted for update when you register a new resource with admin. This can be done in app/admin/model.rb file.

permit_params :list, :of, :attributes, :on, :model

The attributes that you specify here are permitted for update through admin dashboard.

Hope you found this helpful integrating ActiveAdmin with your Rails Project. Feel free to ask questions through comments if you face any difficulty.

Difference between to_s and inspect in Ruby

While running a script in Ruby, we usually want to log data from objects for debugging purpose. puts, p, logger methods are used to log along with to_s, inspect methods to log object. This tutorial will give brief about each method and when to use which one.

 

1. to_s

to_s is very common method used by Ruby programmers to get String representation of object on which it is called. For example,
considering fixnum,

12345.to_s => '12345'

Similarly if you try to use to_s method on Model/ActiveRecord object in Rails, it will give something like,

User.first.to_s
#<User:0x007fd15cc57238>

Which is object's representation in string. User: Class name, 0x007fd15cc57238: based on object id.

Using String Interpolation:
Whenever you use String Interpolation, Ruby calls by default to_s method on objects used in the String interpolation before printing output. For example,

user = User.first
puts "This is #{user} information"
"This is #<User:0x007fefb2002428> information"

This show that while processing string interpolation user object is converted to to_s internally.

2. inspect

inspect method is more of a developer-friendly version of to_s. For Model/ActiveRecord you can check out definition of inspect on APIDock
Considering same example as above,

user = User.first
puts "This is #{user.inspect} information"
This is #<User id: 1, email: "username@example.com", encrypted_password: "$2a$10$D57y73Q9HUXG9Hym3bLl8.MizOdTRxd6NQH6snHi4Q....", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: "2014-10-15 11:19:09", sign_in_count: 13, current_sign_in_at: "2014-10-21 20:10:18", last_sign_in_at: "2014-10-20 17:37:27", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", created_at: "2014-06-30 17:41:06", updated_at: "2014-10-21 20:10:18"> information"

This clearly depicts how much useful inspect is instead of to_s on objects for logging and debugging purposes.

3. p vs puts

When you use puts for printing, then puts internally uses to_s on objects before processing inputs, while p uses inspect on objects before processing inputs.
E.g. Again considering same example,

user = User.first
puts user
#<User:0x007fefb0c690b0>

This just has converted object's reference using to_s
Now tryng with p

p user
#<User id: 1, email: "username@example.com", encrypted_password: "$2a$10$D57y73Q9HUXG9Hym3bLl8.MizOdTRxd6NQH6snHi4Q....", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: "2014-10-15 11:19:09", sign_in_count: 13, current_sign_in_at: "2014-10-21 20:10:18", last_sign_in_at: "2014-10-20 17:37:27", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", created_at: "2014-06-30 17:41:06", updated_at: "2014-10-21 20:10:18">

Thus, you may prefer using p instead of to_s if you are looking purely for logging/ debugging purposes. Otherwise use of these methods purely depends on the required functionality though.

Access specifiers in Ruby

This tutorial will discuss how to define Access specifiers in Ruby and what do they mean for classes and modules where they are being used.

Default Scope

Whenever you define a new method in any class/module the default access specifier that Ruby will use is public.
Thus, all methods defined without any scope are public by default.

1. public

Methods having public scope can be called from anywhere i.e. from outside class as well.

1) public access to instance methods

If public access to instance method is given then those can be accessed from outside of the class but with instance of the class.
One can define scope for methods being defined as public explicitly as well. This can be done as given below,

class TestClass
public
def some_method_a
# method body
end

def some_method_b
# method body
end
end

The above example shows that access specifier public is applied on methods defined after the access specifier is declared, resulting methods some_method_a and some_method_b getting public access.
These methods can be called from any class outside TestClass as given below,

test_objet = TestClass.new
test_object.some_method_a
test_object.some_method_b

This would work as these methods were having public access.

2) public access to class(self) methods

One can give public access to class methods as well.
Now you would wonder what does public access to private methods achieve?
But they certainly achieve privacy of class methods, following sample example will illustrate this,

class User
def instance_method_first
#some code
end

def self.class_method_first
# some code
end

def self.class_method_second
# some code
class_method_first
end
end

From outside public class methods would be accessible as -

User.class_method_first
or
User.class_method_second

As we know by default all methods will have public scope. The instance method instance_method_first and class methods class_method_first and class_method_second will have a public scope and they can be called from anywhere. We can see that they can be called from themselves as well, e.g. class_method_second has called class_method_first.

2. private

1) private class methods in ruby

Question?
Can we make class methods private? If yes, how?
Yes, We can make class methods private using access specifier private_class_method

What does this mean -
This means that private class methods would be accessible to the methods defined in the same class only. They can not be called directly from outside of the class. If they need to be accessed from outside of the class, then there needs to be a wrapper method in the class that has public scope which can ultimately call a private method.
e.g.

class User
def some_instance_method
# some body
end

def self.method_first
# some body
end

def self.method_second
# calling method_first
method_first
end

private_class_method :method_first
end

Now if we try to access,

User.method_first
NoMethodError: private method `method_first' called for User:Class

Then it would give error as show above as it is private and can be accessed from the User class only.

If we try to access,

User.method_second

Then it would work properly as expected.

This way you can make class methods private in ruby.

2) private instance methods in ruby

You can define private instance methods in ruby by specifying private access specifier before defining your instance methods. The private access specifier will be applied on all the methods defined after it's declaration.
e.g

class User
def some_public_method
# code
end

private
def method_first
# code
end

def method_second
# code
end
end

Here both instance methods method_first and method_second will act as private methods. Thus these methods can be called from the instance methods of the same class only. These would not be accessible from outside of the class.

Profiling Rails Apps with Rack-Mini-Profiler

This tutorial will discuss profiling Ruby on Rails Applications using rack-mini-profiler gem. rack-mini-profiler gem helps finding performance bottlenecks by showing speed badge on every page which can be configured to be displayed in particular environments. E.g. development/staging/production environment.

How to Install

You can install Rack-Mini-Profiler gem by command -

gem install rack-mini-profiler

This command will help you install latest stable version of this gem.

Github Source link:

rack-mini-profiler

Integration with Rails Application

1. Add to Gemfile

You need to add this to Gemfile in the environment that you desire, we recommend you to add this gem in your development environment to measure the performance of your pages.

group :development, :test do
gem 'rack-mini-profiler'
end

This will add gem in development and test environments only.

2. Bundle

After adding this gem to your desired environment you need to bundle install so that Rails application gets configured with the gems listed in the Gemfile. This can be done by following command,

bundle install

After this, you need to test by starting the server.

3. Start the Server

Then  you can test how your profiling is done using this gem by starting the server and opening any page of your Rails application. Rails server can be started by following command:

rails server

Nest step is testing your Rails App.

4. Sample output with Interpretations

rack-mini-profiler

This is small snippet how the profiling result is shown by rack- mini-profiler. This shows time required to render the action. This also gives expanded view where it shows the queries executed and the amount of time taken by each query and so on.

Try exploring this gem, you will get more performance monitoring features as you start using this gem.

Conclusion

rack-mini-profiler helps in identifying performance bottlenecks and eliminating them. After checking out facts shown speed badge of rack-mini-profiler you can easily optimise queries and code as needed.

Related Post

To measure performance of Rails Applications, you might want to check out Rails Meta_Request article

Hello world!

Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!

Rails Pluck vs Select and Map/Collect

In Rails, Pluck vs Select can be understood while active record querying. Pluck is used to get array of particular attribute based on particular condition. Same can be obtained using select and then collect on model. This tutorial will help you understand the difference between these ways of collection of specific attribute values.

We will start with an example to understand this.

When you want to select ids users having age great than let us say 20, then in structures query language this can be written as,

select id from users where age > 20;

But, if you want to do it in Rails way then,

Option 1 - Collect
User.where('age > 20').select(:id).collect(&:id)
Option 2 - Map
User.where('age > 20').select(:id).map(&:id)
Option 3 - Pluck
User.where('age > 20').pluck(:id)

Let us see the what does these approaches exactly infer.

Collect/Map

Basically these 2 methods are alias of each other, thus they do one and the same thing. If you want to know more about collect/map, you can refer the post on Collect/Map.

  • Collection of ActiveRecords is returned by querying from the database
  • Then, Loop is run on this collection to collect the ids from the collection of active record
Pluck
  • Pluck directly returns array of the attribute that we pass to it
  • It also selects only those attributes while querying
  • Thus, Rails retrieved array of attribute values instead of array of ActiveRecord
  • Thus, extra loop to get ids from the collection of ActiveRecord is saved while using the pluck method

We will use benchmarking to test the concept that we discussed.

Approach - Collect
puts Benchmark.measure { User.where('age > 20').select(:id).collect(&:id) }
User Load (0.7ms)  SELECT id FROM `users` WHERE (age < 20)
0.010000   0.000000   0.010000 (  0.011173)
nil

Time Taken : 0.011173 s

Approach - Pluck
puts Benchmark.measure { User.where('age > 20').select(:id).collect(&:id) }
SQL (0.7ms)  SELECT `users`.`id` FROM `users` WHERE (age < 20)
0.010000   0.000000   0.010000 (  0.003422)
nil

Time Taken : 0.003422 s

Conclusion

This shows that SQL query executed in both the cases is exactly the same, but time taken by pluck approach is considerably less than that of collect/map with select. This was queried on database having users around 10k. If you have very large database then the difference would matter to you when querying.

Rails Pluck Multiple Values/Columns

You can pass multiple columns/attributes for pluck for active records querying and retrieving array of particular attribute. This can be done as follows,

User.where('age > 20').pluck(:id, :name)

This will give you array of arrays in which each array will contain id and name of user.

Reference

You can refer APIDock for more information of Pluck. Let us know through comments if you have any concern/feedback.