My experience at RubyConf Brasil, 2014

This was my first time attending Rubyconf Brasil and it is one of the best experience I have ever had at a conference. The conference for the speakers started a day early. There was a barbecue party arranged at the Codeminer HQ. It was a good idea since a lot of speakers were not from Brasil, so it made it easy to get to know a few people. Moving onto the venue for the conference. It was at the Frei Caneca Theatre. It is a 16 floor building which has a theatre for the conferences, a shopping mail, many restaurants, corporate office and a lot more which I could not explore. The conference was at the 5th and the 6th floor. Here is a picture of the theatre.

Theater

People started coming in around 8:00 am and by 8:15, it was jam-packed. A 1000 people attended the conference. It started with George Guimarães’s talk on “Dogmatism and software development” and followed by a coffee break, it was Ruslan Synytsky’s talk on Jetlastic’s new ruby implementation. Both the talks were interesting and were single track conference.

On a side note, most of the talks were in Portuguese, so there were translators available for all the English-speaking people.

After Ruslan’s talk, conference was divided into a 2-track conference. Next up was talks on Elastic Search and Puppet using Ruby in the other track. I choose to attend ElasticSearch talk since it is an area of interest to me. Pedro Franceschi  spoke about elastic search and how using it in its core way is the best approach rather using a ruby wrapper for it because it limits the way you could use it. Couldn’t agree more with him!!

It was time for lunch. There were so many restaurants in the building, everyone had a varied choice of what they want to eat. After the lunch was talk on “Quality software engineering for your data center” by Ben Langfeld. I met Ben at the barbecue and was already looking forward to his talk. He is an Englishmen but speaks Portuguese just like a local. Even though it is always very difficult to keep pace with the talks which are just after lunch. But it turned out to be one of the most interesting talk at the conference. He talked about Devops and how it is not something of a middle ground between development and Operations and is much more. In the other track, it was about “Migrating an application from MongoDB to PostgreSQL” by Marcio Trindade. I wanted to attend both the talks but I have just not found a way to teleport yet :(

Next up was me. I think it went well as many people came up to me and appreciated it. Anyways I really enjoyed the talk and learned some very important lessons about giving talks. In the other track was a talk on “iOS on Rails” by Cezar Carvalho Pereira. Another talk which I wanted to attend, but definitely not at the cost of skipping my own talk :). Just before the coffee break, there was one more talk scheduled. And it was time for Vipul and Prathamesh to take the stage. They talked about “Building a ORM with AReL: Walking up the (AS)Tree”. I could not follow the whole talk as I was still making notes of how I could have improved my talk and was asking for reviews from people sitting around me. One of the most important review which I received was that I should have spoken a little slow as not many people understood English and not all of them had the translators. Point noted for the future..!!
In the other track it was about “Convention on creating and deploying Rails applications” by Eduardo Fiorezi.

Followed by another coffee breaks, it was time to choose between “SOLID principles through tests” by Sebastian Sogamoso and “My (Re)Architecture process, from Zero to Hero!” by Lucas Martins. Well I have been reading a lot about Solid Principles and how TDD fails to drive us towards the correct design, I choose to attend this one. Because topics like these are open to debate and everyone has their own opinion, and I love to hear discussions about this. It was also one of the most interesting talks at the conference.

Last talk for the day was a very unique talk. It was titled “Leadership for the Future” by Murilo Gun. He is a standup comedian, entrepreneur and have spent 10 years in technology. It was one of the talks I badly wished I knew Portuguese. He talked about the bets he places for the future. Although the translator was doing a great job at translating, some jokes were just meant to be understood in Portuguese.

IMG_20140829_192949 party

And it was finally the end of Day 1. Wait.. it was the end for the talks not the conference. Now it was time for happy hours at a pub very close to the conference. Made some friends here too.

 

 

Day 2 of conferences usually have less attendance for the morning sessions, but not here. I guess it was because Koichi Sasada was supposed to speak about “Growing the Ruby Interpreter”. Nobody wanted to miss this one. After this it was time for a coffee break and then another choice to make between “Integration Testing SOA Rails Apps” by Travis Douce and “Testing the security of your applications with Metasploit Framework” by Daniel Romero. This time around I did not have to make a choice as I had an extended coffee break talking to few people.

Then it was another of these design-tdd related talk. It was titled “Improve your Rails application design with better TDD” by Marko Anastasov. By now you would have guessed that I would have attended this one. Marko started off by showing a really complex piece of code and how he used TDD and design patterns to arrive at the correct design and maintainable codebase. In the other track Thiago Scalone spoke about “MRuby – Minimalistic ruby on browser or mobile”.

Followed by lunch, it was time to hear about “Tricks that Rails didn’t tell you about” by Carlos Antonio da Silva. It was another just-after-the-lunch talk, so you know it was really hard for me to follow all the time. But I really liked his talk and would definitely wait for the videos to be published for this one. The next talk I attended was about javascripts titled “You still don’t know how to write proper Javascript for Rails applications” by Jean Carlo Emer. In the other track, Ricardo Valeriano and Arthur Zapparoli spoke about “Lotus: A true OO Ruby Web Framework”.

Next up was Matt Campbell. He is a product of a Rails Bootcamps and he talked about how he left his well-to-do finance job one day and joined a Rails bootcamp, his experiences of the bootcamp and how the education system is screwed in the US. Personally I do not think bootcamps are a replacement of a college degree. And they would be of help to someone who has a programming background and want to learn something new. But that’s just my opinion. In the other track Hanneli Tavante spoke on “Java headache? Torquebox!”. Next up was a talk on “Rock-Solid Web APIs with Rails” by Carlos Souza and “Building your own Credit Card Company” by Eduardo Mourão. I attended the latter one. But unfortunately took the wrong translator with me and it took me a little while to realize this. And by the time I realized it was pretty late. But it looked like people really enjoyed his talk.

Now we were very close the wrap of the conference. Fabio Akita spoke on “The last 10 years through Rails and Ruby” and how we should all follow our passions and do not worry about the consequences. One of the things I really liked was how he accepted the fact that even after giving over 100 talks, he is still nervous every time he gets on to the stage. It was a good closing key-note and at the end all the speakers did some pictures on the stage and also took a selfie..:)
image

Overall it was a great conference, great experience for me as it was my first conference abroad and lots of memories. And as we say it here, OBRIGADO..!!

Image | Posted on by | Tagged | 1 Comment

Tussle of the State Machines

There’s no shortage of Ruby state machine libraries (assm, state_machine, etc.). However when we needed to implement dynamic state machine we didn’t find one.

The Problem

We needed a polymorphic class that could have different state machines triggered in it depending on some condition. Basically, here is what we wanted to achieve:

class Call
 include Mongoid::Document

 field :scheduled_at, type: DateTime 
 field :is_existing_customer, type: Boolean
 field :note

 belongs_to :callable, polymorphic: true

 case callable_type
  when 'Car'
   state_machine :state, :initial => :fresh, namespace: 'car' do
    event :schedule do
     transition [:fresh, :schedule] => :scheduled
    end
    # ...
    # ...
  end

  when 'Personal'
   state_machine :state, :initial => :fresh, namespace: 'Personal' do
   event :schedule do
    transition :fresh => :scheduled
   end
    #...
    #...
  end

  when 'any other'
   #...
  end
 end

Now the problem was that AASM State Machine does not support multiple state machine in a single class. So we tried to achive it through state_machine gem with namespaces. However, we could not have same state field even under the namespaced state machine in a single class.

The solution!

We wanted a state machine that could be easily integrated with other Ruby objects. So we decided to define a state machine as a separate class and selectively apply it to our Rails models. We were using MongoDB, so we embedded these objects.

class CarStateMachine
 include Mongoid::Document
 include AASM

 field :state
 embedded_in :call

 # no need for name space and we can use AASM directly
 state_machine :state, :initial => :fresh do
  #states: fresh, scheduled, lead, succeed
  event :schedule do
   transition [:fresh, :schedule] => :scheduled
  end
  #...
  #...
  end
 end
class PersonalStateMachine
 include Mongoid::Document
 include AASM

 field :state
 embedded_in :call

 #states: hello, meet, bye
 state_machine :state, :initial => :hello do
  event :wow do
   transition :hello => :meet
  end
  #...
  #...
 end
end

Now, the model can access these embedded objects using a call_state method, that returns the embedded object based on callable_type of model!

class Call
 include Mongoid::Document

 field :scheduled_at, type: DateTime
 field :is_existing_customer, type: Boolean
 field :note
 field :callable_type
 
 embeds_one :car_state_machine
 embeds_one :personal_state_machine
 
 # Method to access state machine
 def call_state
  case self.callable_type
   when 'Car'
    self.car_state_machine || self.build_car_state_machine
   when 'Personal'
    self.personal_state_machine || self.build_personal_state_machine
   end
  end
 end

Here is a sample output of a Call model using different state machines dynamically!

call = Call.first.callable_type # => "Car"
call.call_state.state # => 'fresh'
call.call_state.schedule! 
call.call_state.state # => 'scheduled'

#####

call = Call.last.callable_type # => "Personal"
call.call_state.state # => 'hello'
call.call_state.wow!
call.call_state.state # => 'meet'
Posted in Ruby | Tagged , , | Leave a comment

PDF to Plain Text processing using docsplit

As Rubyists, don’t we just love searching for gems to do our work for us :) But, that does not always work, does it? There are times when we don’t find solution and need to fix it ourselves. Do we remember to contribute back to the community? Here’s a similar story and some information about PDF to plain text parsing using pdf-reader and docsplit.

In one of our projects, we wanted to read data from PDF and convert it to “plain text”. As expected, we started searching for a gem that could help us achieve it and we quickly found pdf-reader. It was working as expected with Portrait orientation. However, when we tried to use the Landscape orientation, it failed!

On reading the code in pdf-reader, we found that it does not provide any option to parse a page in landscape orientation! When we passed a “Landscape” page to pdf-reader, it converted that page into plain text but the order of data changed and sometimes we even lost data. We tried to find a solution to this and fix pdf-reader but unfortunately it was getting really crazy and we discarded our attempt in light of our current need. We shall re-attempt this again soon.

Here’s what happened when we tried converting PDF to “plain text” using “pdf-reader”

After installing the gem, we tried the following code.

  reader = PDF::Reader.new(file_path)
  text = reader.pages[page_number].text

We get following output for sample text

F\nD\no\nm\nd\no\nt\nm\no\na\nt\ne\nn\nt\ne\nl\np\na\nS

This was a setback. So, we decided to look for an alternate solution. That’s when we came across docsplit. But, even with this we had the same problem. So we decided to read source code and we found docsplit internally uses pdftotext utility and we can pass different arguments to pdftotext but this was not implemented in docsplit so we contributed to that.Sanjeev Jha has submitted this pull request.

Steps to convert PDF to plain text using Docsplit

After installing the gem, we have several options we can pass to Docsplit. We chose the “-raw” option.

  Docsplit.extract_text(file_path, {pdf_opts: '-raw',  
       pages: from_page_number..to_page_number, 
       output: 'tmp_text_file'})

where,

pdf_opts: Format in which you want your text.

Docsplit generated a text file for each page in the current directory. (we can optionally specify output directory for the text files). With this raw option first page of the pdf file got converted to file whose contents were like this

Sample
text
in
vertical
format
for
demo
PDF.

But here was a problem – we wanted to do some processing on the text and getting the text on a separate line would not help. Suppose we have text

Employee name   abc xyz  a111

We know that the employee name and number is separated by “3 spaces” and the text before these 3 spaces is the name of employee. However, as shown above, the employee number can have spaces too (“abc xyz” or “a b c”)! So the above -raw option would not help us extract the name and number. So we searched for other options and I came across the ‘layout’ option.

  Docsplit.extract_text(file_path, {pdf_opts: '-layout',  
        pages: from_page_number..to_page_number, 
        output: 'tmp_text_file'})

Now, with the layout option first page of the pdf file got converted to text file whose contents were like this

Sample text in vertical format for demo PDF.

This is exactly what we wanted and were able to complete our work properly! To ensure sanity, we migrated entirely from pdf-reader to docsplit.

Lesson Learnt

Before using any gem check whether it fulfills all your requirements and if possible, try to contribute so that other people will not face same problem.

Posted in Ruby | Tagged , | Leave a comment

What makes rspec3 so interesting?

Gautam Rege:

Here is a list of things that rspec3 has in store for us.

Originally posted on rails learning:

Being an rspec fan I have been waiting for quite some time for the rspec3 final release. rspec3 has finally been released and it’s ready for production use. There are many interesting changes that has been incorporated in rspec3. Thanks to myron, Andy and david and other contributors. Here are the few changes that makes testing more fun: Changes in rspec-expectations:Compound Expectations: Composing a expectation using two or more expectations is called compound expectation. Here is the example:

1 1
# In rspec3
RSpec.describe String do
example “expect to be a instance of String and it should be equal to ‘RUBY IS AWESOME'”
string = “RUBY IS AWESOME”

expect(string).to be_a(String).and eql(“RUBY IS AWESOME”)

View original 822 more words

Posted in General | Leave a comment

Managing images within AWS S3, without re-processing

Gautam Rege:

When you want to move images from one S3 bucket to another – do you bang your head against the wall? Even if you write a program to do that, does it take ages? Here is a neat and quick way to manage your images in AWS S3 without re-processing them!

Originally posted on foorubypho:

Its common to upload & retrieve images from Amazon S3. We also use existing one’s to create modified versions. Similarly, once our client came up with a requirement that he needs to duplicate his data along with images & then user can modify the cloned data as needed.

Consider an example of a car where,

  • car has several models/variants such as base, standard, superior etc
  • each variant contains some features same as they are in previous variant
  • engineers create a base variant first & then using same data they can customize new variant & so on
  • so engineers gets the previous variants data as is & can update as needed.

This data contains a lot of high resolution images for “minor details” such as:

  • Exterior images as options available in body parts, bumpers, vinyls, graphics, rear bumpers, spoilers etc
  • Interior options available such as leather color, steering types, mounted controls…

View original 681 more words

Posted in General | Leave a comment

Building web apps with Rails4 and AngularJS in 15 minutes

While learning AngularJS to make a single page app using Rails4, I found some good videos and blogs. However, I did not find any simple example for CRUD operations that made me easily understand the integration between Rails4 and AngularJS. So in this tutorial post, I explain how to create basic CRUD operation using Rails4 and AngularJS.

Here is my git repository for the complete code Github

Create rails project


$ rails new rails4_crud_with_angularjs

Create User model


$ rails g model user

file db/migrate/[timestamp]_create_users.rb


class CreateUsers < ActiveRecord::Migration
 def change
   create_table :users do |t|
     t.string :first_name
     t.string :last_name
     t.string :email
     t.string :phone
     t.timestamps
   end
 end
end


$ rake db:migrate

app/model/user.rb


class User < ActiveRecord::Base
 validates :first_name, :last_name, :email, presence: true
end

Create Users controller


$ rails g controller users

Create the CRUD operation in users controller and send JSON response. The code sample is here

Add angular gem

In Gemfile add these two gems.


gem 'angularjs-rails'
gem 'angular-ui-bootstrap-rails' #for bootstrap UI


$ bundle install

Setup layout

Adding ng-app and ng-view indicates that we have an AngularJS app in the page.


<html ng-app="myapplication">
 <head>
   <title>Rails4CrudWithAngularjs</title>
   <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
   <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
   <%= csrf_meta_tags %>
 </head>
 <body>
   <div class="container" ng-view>
     <%= yield %>
   </div>
 </body>
</html>

Create an angular controller

First let’s create a directory for our controllers. You can name it whatever you want.

$ mkdir -p app/assets/javascripts/angular/controllers

Now create users_controllers.js file. Here I have used the same naming convention as Rails.

// app/assets/javascripts/angular/controllers/users_controllers.js
var myApp = angular.module('myapplication', ['ngRoute', 'ngResource']);

‘myapplication’ is ng-app name.

Add Factory

Factory is the angular provider and you can learn more about it here. It basically interacts with the rails server and processes the json response.

myApp.factory('Users', ['$resource',function($resource){
 return $resource('/users.json', {},{
 query: { method: 'GET', isArray: true },
 create: { method: 'POST' }
 })
}]);

myApp.factory('User', ['$resource', function($resource){
 return $resource('/users/:id.json', {}, {
 show: { method: 'GET' },
 update: { method: 'PUT', params: {id: '@id'} },
 delete: { method: 'DELETE', params: {id: '@id'} }
 });
}]);

‘Users’ factory is used for getting the collection of users and creating users. ‘User’ factory is used to get the user details, update the user or delete the user.

Add Routes

Angular routes are used for deep-linking URLs to controllers and views (HTML partials). It watches $location.url() and tries to map the path to an existing route definition.

myApp.config([
 '$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
 $routeProvider.when('/users',{
    templateUrl: '/templates/users/index.html',
    controller: 'UserListCtr'
 });
 $routeProvider.when('/users/new', {
   templateUrl: '/templates/users/new.html',
   controller: 'UserAddCtr'
 });
 $routeProvider.when('/users/:id/edit', {
   templateUrl: '/templates/users/edit.html',
   controller: "UserUpdateCtr"
 });
 $routeProvider.otherwise({
   redirectTo: '/users'
 });
 }
]);

In the code above, I have added the controllers UserListCtr, UserAddCtr, UserUpdateCtr for listing users and to create and update users.

Add Angular templates

Now we need to add templates. I have stored them in public/templates.

If we create a file public/templates/users/index.html with some arbitrary content, we should be able to see it in the browser. Here is a sample template for users.

 CRUD Actions

Now our setup is done and we are ready for processing CRUD operation.

Index Action:

myApp.controller("UserListCtr", ['$scope', '$resource', 'Users', 'User', '$location', function($scope, $resource, Users, User, $location) {
  $scope.users = Users.query(); //it's getting user collection
}]);

‘UserListCtr’ this controller listing users. you can check index.html here I am not explaining index template it’s straight forward angular template, you can read more about it here.

Create Action:

myApp.controller("UserAddCtr", ['$scope', '$resource', 'Users', '$location', function($scope, $resource, Users, $location) {
  $scope.save = function () {
    if ($scope.userForm.$valid){
      Users.create({user: $scope.user}, function(){
      $location.path('/');
    }, function(error){
      console.log(error)
    });
  }
 }
}]);

‘UserAddCtr’ this controller create user. you can check new.html here. Users.create() calling users controller create action. create() action we defined in ‘Users’ factory.

Update Action:

myApp.controller("UserUpdateCtr", ['$scope', '$resource', 'User', '$location', '$routeParams', function($scope, $resource, User, $location, $routeParams) {
   $scope.user = User.get({id: $routeParams.id})
   $scope.update = function(){
     if ($scope.userForm.$valid){
       User.update($scope.user,function(){
         $location.path('/');
       }, function(error) {
         console.log(error)
      });
     }
   };
}]);

‘UserUpdateCtr’ this controller update the user. you can check edit.html here. Users.update() calling users controller update action. update() action we defined in ‘User’ factory.

Delete Action:

For delete user I am not creating separate angular controller. I am writing deleteUser event in ‘UserListCtr’  controller.


myApp.controller("UserListCtr", ['$scope', '$http', '$resource', 'Users', 'User', '$location', function($scope, $http, $resource, Users, User, $location) {

  $scope.users = Users.query();

  $scope.deleteUser = function (userId) {
    if (confirm("Are you sure you want to delete this user?")){
      User.delete({ id: userId }, function(){
        $scope.users = Users.query();   // after delete user get users collection.
        $location.path('/');
      });
    }
  };
}]);

User.delete() calling users controller destroy action. delete() action we defined in ‘User’ factory.

In  public/templates/users/index.html for adding ‘Remove’ link


<a href="" ng-click="deleteUser(user.id)">Remove</a>

Remember href should be blank, if you add href=”#” it will call default route in your application.

I hope this blog helps those are started development in Rails + AngularJS.

Posted in Javascript, Ruby on Rails, Tutorials | Tagged , | 2 Comments