Thursday, December 31, 2015

Programmers and Obsessive-Compulsive Disorder: a hint for beginners



I think we, programmers, all have felt, one way or another, that compulsion to put things in a certain order.

Identation is an example. In the last 30 years programming, I've met just a few programmers who couldn't care less about identation. None of them is still a programmer by now. It seems this feeling about organizing program's lines is essential when it comes to be a good programmer or not.

It is kind of a positive Obsessive-Compulsive Disorder. And I say positive because keeping things organized helps a lot in programming.

Have you ever felt unconfortable when you add a column to a table using a migration and then you have things like

  create_table "courses", force: :cascade do |t|
    t.integer  "user_id",           limit: 4
    t.string   "title",             limit: 100,   null: false
    t.datetime "created_at",                      null: false
    t.datetime "updated_at",                      null: false
    t.binary   "short_description", limit: 1024
    t.binary   "long_description",  limit: 65535 
  end

Here you clearly see that columns short_description and long_description are out of order. And, worst of all, they are going to be out of order in your table. I mean out of order because I assume all columns should come before created_at and updated_at. This is so natural to me that I can't even explain why is that so. But it is! Maybe it is really Obsessive-Compulsive Disorder.

The good news for beginners is: you can safely edit your db/schema.rb to fix this!

In spite of what Rails writes in this file by default, you can safely edit db/schema.rb, as long as you do nothing more than changing the order of some lines inside a create_table.

In the case above one may edit db/schema.rb and write


  create_table "courses", force: :cascade do |t|
    t.integer  "user_id",           limit: 4
    t.string   "title",             limit: 100,   null: false
    t.binary   "short_description", limit: 1024
    t.binary   "long_description",  limit: 65535 
    t.datetime "created_at",                      null: false
    t.datetime "updated_at",                      null: false
  end

Then, the point here is:

  1. Generate all your migrations
  2. Run rake db:create:all
  3. Run rake db:migrate
  4. Edit db/schema.rb and place all columns in the correct order
  5. Run rake db:drop:all && rake db:create:all && rake db:schema:load
And voilĂ ! There you have all your columns, in all your tables, in the correct order, no matter how you created them.


Monday, December 28, 2015

Phusion Passenger x Rails Composer



I host my customers' websites in VPS servers rented from HOST1PLUS (http://host1plus.com), and I use Apache webserver with Phusion Passenger module to do so.

Up  to this point, nothing so special. But a few days ago I started testing Rails Composer (https://github.com/RailsApps/rails-composer). Everything worked great while I was using my development environment with Webrick, but when I finally tried to publish a small test app in one of my VPS servers, nothing worked.

Rails Composer offers the option to install better-errors, a wonderful gem. It displays a details' screen with all about your errors, which is great, considering that debugging requires all information available sometimes. And when it comes to web apps, you may say this again, and again...

Well, I installed better-errors and when I first tried to run my app I got just the dump screen with error details!

It said, sumarizing, that gem nokogiri could not be loaded. Strange, 'cause I had executed 'bundle install' and knew all gems were there. I followed the procedure to empty my gemset and then installed everything again. Nothing... Same error.

I tried almost everything I could imagine. Then, suddenly an idea came to my mind.

It happens that Rails Composer uses the strategy of creating a private gemset for each web app. The gemsets are stored under .rvm directory and we have always a global gemset for each Ruby version installed and as many private app gemsets as you create.

But be careful!

It seems that Phusion Passenger does NOT recognize private app gemsets. I tried almost everything, as I said before, including changing permissions. Nothing helped! But when I changed back to global gemset it all worked fine.

In order to move back you just have to edit .ruby-gemset file, which is under your app root directory. Remove whatever is written there and write just the word 'global' (no quotes, please).

After doing this, just run 'bundle install' again and you'll see all your gems which were installed in the private genset being installed again, now in the global gemset.

In the next article I'll discuss the advantages and problems of having private gemsets for each app. 

See you there.


Thursday, December 3, 2015

A small trick to use AJAX with Rails



Reloading the whole page at every new request is not a good solution sometimes. But that's exactly what Rails does by default, as we all know. Ajax, as always, is a good solution to prevent this and Rails has its way to use Ajax.

I'm going to talk here about another way to use ajax inside rails, circunventing a small problem.

Let's assume I have a fragment like this

app/views/customer/fragment.html.erb
<div>
  <h1>Just a small test</h1>
</div>

and I what this to be displayed inside a certain area in my page whose id is "ajax-content-area". Something like this.

app/views/customer/main_customer_area.html.erb
<html>
  <body>
    <button class='btn' onclick='ajax_call_fragment();'>Click to show fragment below</button>
    <div id="ajax-content-area"></div>
  </body
</html>

Let's also assume main_customer_area.html.erb is already in my screen. It's been renderized by a call to customer#main_customer_area, according to Rails standards. Now I want to call my fragment.html.erb and place it inside the corresponding <div>. For doing so I create a route:

config/routes.rb:
get '/customer/ajax/fragment', to: 'customer#fragment'

and a method fragment

app/controller/customer.rb
def fragment
end

Now, the final piece:

app/assets/javascripts/application.js
function ajax_call_fragment() {
  var displayArea = $('#area-content-area');
  var myUrl = '/customer/ajax/area';  
  $.ajax( {
    url: myUrl,
    success: function(ret) {
      displayArea.html(ret);
    },
    error: function(ret) {
      displayArea.html("<h3>Put your error message here...</h3>");
    }
  })  
}

Now thar we are ready, when you click the button in main_customer_area, something really bad happens!

Your fragment really appears, but it comes wrapped in the main layout!

As you said nothing, Rails will proceed ad always. It will receive the ajax request for '/customer/ajax/area'; will validate the route and, as said in config/routes.rb, will invoke method fragment at Customer controller. the method says nothing, so Rails will follow its usual procedures. Will search for a view named fragment.html.erb inside app/views/customer/. It is there and then Rails will render it inside the main layout and send it back to browser. Ajax will receive it and put it inside the desired <div> object.

Everything all right, but not what you wanted in the screen. Yeah... because your fragment will be wrapped by the mais layout! You'll have it as a copy of you page inside your page. Banners, menus... all pieces inside your main layout will duplicate.

Of course you may create a new (almost) empty layout, say

app/views/layouts/emptylayout.html.erb
<%= yield %>

and rewrite your method fragment as:

app/controller/customer.rb
def fragment
  render layout: 'emptylayout'
end

This will surely work. But you'll add unnecessary complexity to yout app, creating a new layout for doing nothing.

I'll show you an easy way to achieve the same without this.

Rewrite your method fragment as

app/controller/customer.rb
def fragment
  render layout: nil
end

Yes, you may do such thing as render a nil layout. The result is exactly what you want. Rails will pick the corresponding view and pass it away, since it was told not to wrap it in a layout!

This, of course, is not a suggestion to forget all Rails support to Ajax. It's just another cool way to get things done and a new information: nil layouts are possible!

You never know when this kind of thing may be necessary.

Sunday, November 29, 2015

TxtDb: An easy to use gem for prototyping databases



You are trying to prototype a website fast, to show something to a potential customer. You are using Heroku or C9 or any other similar platform. Then you have to lose some time configuring a database, just to pupulate it with a few data to show to your customer.

Wouldn't you like to have a tool to make this database task easier?

If so, now you have it!

TxtDB is a Ruby gem that implements all you need to have a small textfile-based SQL database, ideal for fast prototyping.

It is part of a suite of tools I'll be publishing this December to make the lives of Ruby on Rails developers easier.

Time is money. Or at least so they say. For me, time is something I may spend with my family, my friends, my books... Why spending it with tasks you may avoid?


Thursday, October 8, 2015

Don't give up RVM



Well... I'm a Linux user.

This is not a big deal, of course. A large number of developers prefer Linux as OS. Windows is such a pain in the ass!

But the question is that I moved from Debian 8 to Fedora 22 recently. Most of my Linux life I used Debian for desktops and Slackware for servers. I keep my Slackware servers running, but gave up Debian recently. Two main reasons:

  1. It was taking some time for me to perform some (suposedly) easy tasks, like configuring my wireless connection. I use Dell laptops at home (a D620 and a Vostro) and my wireless cards lacked firmware under Debian 7 and 8. I had to download the firmware somewhere else just to see the wireless light goes on in my laptop panel, then install a software to "cut" the correct firmware and then configure wireless almost manually. I know most people do not consider this a problem, because they like to do this kind of things and because you do it once, when you install your OS and never more. But to me this means losing time and I don't like to waste my time, 'cause I always have lots of things to do.
  2. I tested Fedora 22 and it was just perfect. Everything worked fine from the begining. All hardware recognized, up and running, no need to separately install anything. Almost as if I were using Windows (may God protect me from this!) but without all the bullshit and all that pain in the ass mentioned above.
As a Ruby on Rails developer, I found it great that Fedora packages included Ruby, Rails and all other tools needed to start working. Then I didn't even installed RVM.

To my regret!

This very day I'm writing, I received a task from a company. This task involved creating a small piece of software. But... in order to comply with all other software this company does, I had to use a gem named pah in order to create the project.

I installed the gem pah. Everything all right up to now, exactly as the guy falling from the 50th floor said when passing by the 20th floor...

This gem pah, used only Ruby 2.2.2, but my environment was configured for Ruby 2.2.3, because Fedora keeps updated with the newest versions of everything. A big community may surely do this.

But now I had a difficult task in front of me. Downgrading a package is not difficult, of course. But adjusting all my current developments back to Ruby 2.2.2 would mean a lot of work. Then I moved back to RVM!

This was a great lesson to me. And for all developers, I believe. Don't give up RVM. It is a great way to keep many Ruby versions running in the same machine without this install/uninstall/downgrade/upgrade bullshit.


Tuesday, September 8, 2015

It wasn't off the rails... I was!

Remember last post? It wasn't Ruby running off the rails. I was just me?

It seems I forgot a basic rule: go through assets pipeline!

When you're dealing with non-public assets, always use the assets pipeline, for it is going to solve assets location disregarding the web context.

Consider the case of the last post again, so we can understand exactly what happened.

In my bootstrap carousel images I was saying something like

<img src="carousel/image001.jpg" />

When I was visiting the page by the root route "/" my src element was pointing correctly to the image resource and the image was displaying correctly. In my routes.rb the root route was

root 'welcome#index'

Rails maps this to the URI "/", of course. Then we should have "/" and "/welcome/index" routing to the same point, and so we have. but  just inside Rails, and this is the point here.

When I do not use assets pipeline, bu try to point to a certain asset myself, as I did, you bypass Rails and then your are depending on another thing: the we context! 

And, as it happens, the web contexts for "/" and "/welcome/index" are different, so my images disappeared in the second case, even when displaying correctly in the first one.

The solution?

Easy as pie! Do as I said and go through the assets pipeline. In other word, go through Rails framework and say something like

<%= image_tag('carousel/img001.jpg') %>

With this you'll be saying to Rails something like "Hey! Find my asset your way. It's your business, not mine!"

Hope this may help other in the future. And please, send me your doubts when you think Ruby is running off the rails. I can't tell you I'll have a solution for all cases, but I may tell you I'll research a lot before giving up.

Friday, September 4, 2015

When things go off the rails

... and then I was dealing with my website http://borntoraiseheaven.org, which I intend to make available to public in a few days. Everything is ok and I am now joining the pieces together. This is the image of the homepage.



As you may see, this this homepage is the view Welcome#index. And, of course, my config/routes.rb says

get 'welcome/index'
root 'welcome#index'

as it must be. But that single button saying "Homepage" is defined by

<a class="btn btn-block" href="/welcome/index">Homepage</a>

and then points to the same root route, right?

Then, why when I click the button I got this?


Yeah! My beautiful bootstrap carousel now displays no images!

I saw the trace of the server, I asked some expert friends... nothing! Nobody may point me a reason for this to happen!

Then I suddenly realized that sometimes things go off the rails. And I mean no pun when I say this! It's is not just Ruby on Rails, but every programming language sometimes goes off the rails and does exactly what we don't want it to do.

Why does this happens? Who knows! Maybe only God, in His infinite wisdom, knows the reason why programming languages sometimes tend to make us crazy.

This blog is focused on Ruby on Rails, but sometimes I'll talk about other programming languages I use to deal with, like PHP and Javascript...

Oh, please, don't get me started about Javascript! According to AndrĂ© Guanabara, a friend of mine from Rio de Janeiro, Javascript is a language that tends to make you go from heaven to hell, and all the way back to heaven, in just a few moments. A very powerful language, indeed, but also one of the hardest to deal with, according to his opinion and mine. Even when you use things like jQuery, a life-saving library. jQuery surely saved the sanity of many  programmers, but it also have its tricks.

These things happen for us to understand our mothers when they told us to choose simple and lucrative professions, such as brain surgery ... That's what I sometimes think.

By the way... may someone help me with my bootstrap carousel?