Sunday, January 31, 2016

Gem SaneTitle: the first fruit



I posted an article here yesterday asking for suggestions about Ruby gems people would consider useful, specially when using Rails.

This morning I received an e-mail, unfortunately unsigned, with the first suggestion: a gem to receive a string and use it to generate a sane file name to be used in a URL.

This is exactly what happens here at Blogger, when you post an article. This article, for instance, is called "Gem SaneTitle: the first fruit" and it will be saved as gem-sanetitle-first-fruit.html. All in lower case; special chars removed, only letters and numbers remaining; no spaces, all of them replaced with hyphens.

As a result of this suggestion, here is the first fruit of this effort to create useful gems: SaneTitle.




The gem is quite simple and I'd be pleased if people could improve it. It's there at GitHub, it is open-source and you just need to fork it and code. Or post suggestions and issues at the GitHub page.

By the way, my GitHub area (https://github.com/EdDeAlmeidaJr) has many interesting projects and I'd love to receive suggestions or improvements on them. Feel free to follow and fork whatever you want.




Saturday, January 30, 2016

Ruby gems: any ideas?



I need suggestions for good useful Ruby gems.
Specially those you'd consider to be useful when using Rails.
Please, if you have some suggestions, send me at

edvaldoajunior@gmail.com

We may work together in your idea or I may implement it by myself.
In any case I'll give you the credit for the idea, of course.

Tuesday, January 26, 2016

Ranking of languages



I'm going to interrupt for a while the series of articles named "Mutatis Mutandis", where I'm discussing the changes in Rails defaults, just to show you the ranking of increasing popularity of languages.

Strange as it seems, Java is the language whose popularity grew more in 2015. Ruby is in the 10th position, followed closely by some "dinosaurs" like Pascal and Delphi (Object Pascal).

While all this happens, PHP is still in the 6th position, but its popularity is decreasing faster than Ruby's is growing.



This fact may be better understood if we look another table, listing job offers in 2015.


As you may see, PHP is not even listed in this chart. Maybe one of the reasons for this is the fact that web business requires more speed and flexibility now than ten years ago. And PHP frameworks, and said PHP creator Rasmus Lerdorf, are all bad when it comes to these things. Zend  Framework, for instance, is solid and stable, indeed, but serves as an example of how bureaucratic a framework can be.



Friday, January 22, 2016

Mutatis Mutandis (1)



As I said in the last article “Do not change conventions without good reason” (http://rubyofftherails.blogspot.com.br/2016/01/do-not-change-conventions-without-good.html), there are certain things one can change in the conventions of Rails without doing any harm.
 
In fact, there are certain things you may need to change in order to keep the principles of Rails, like DRY, as I already said in my previous article “Rendering and the DRY principle” (http://rubyofftherails.blogspot.com/2016/01/rendering-and-dry-principle.html).

That's why I opted for the latin expression "mutatis mutandis" for the title of this series of articles. For those who never studied latin at school, "mutatis mutandis" means "changing what must be changed" or "when all things needed were changed".
 
One of the things you may, and sometimes need to, change are the routes in config/routes.rb.
 
If you used scaffold to create your entities, your config/routes.rb probably contains now a list of things like
 
resources :customers
resources :products
resources :users
resources :photos
 
This means Rails will add, by default, a set of routes to make your job easier. Taking the case of resources :photos, the resulting routes will be
 

 
If you wish to change these routes according to your needs, no problem. Provided, of course, that you create all routes necessary to you application and include all the parameters needed, there is no problem in changing this particular default. On the contrary, personalize your routes is perfectly normal and sometimes necessary. Let’s consider the following situation.
 
You are creating an application where a certain photo must only be shown to authenticated people. And you are using a token authentication. Then you may have to change the route /photos/:id to a more complex route /photos/:id/token/:tkn.
 
Same happens when you sent your user who forgot his password a link to create a new password by e-mail. This kind of e-mail  usually has an expire time which is persisted in a table in your database. Maybe you created columns in your users table (I do NOT recommend this) to indicate a certain user required a password change and when. But if you learned well how to model a database, you haven’t done that! You certainly have a table, say changepass, with three columns just for these situations: id, the primary key of the request; user_id: a foreign key referencing the user asking for a password change; and expire_time, the time the request will expire. Then you may need to add a totally different route to your resources :users, say
 
/users/changepass/:reqid, to: ‘users#changepass’
 
And then you’d create two methods, changepass and expired_request? in your app/controllers/user_controller.rb
 
def changepass
    request = Changepass.find(:reqid)
    if (expired_request?(request.expire_time))
        render ‘changepass_screen’
    else
        render ‘expired_request_screen’
    end
end
 
def expired_request?(exp)
  Time.now > exp
end
 
As you may see, it is possible to create new routes. In the next article I’ll write about ignoring the routes automatically generated by resources and creating your own set of rules.

See you.

Thursday, January 21, 2016

Do not change conventions without good reason



Rails framework privileges convention over configuration (https://en.wikipedia.org/wiki/Convention_over_configuration).
 
We hear this all the time, but what exactly does this mean?
 
This means that when you are using Rails framework, you just don’t need to care about naming many thing, where putting many things, where this or that resource will be searched for and so on. And you don’t need to care about these things because the Rails framework ‘knows’ these things.
 
Let’s take a look at tables, for instance, just to help us make it clear.
 
If I create a model named User, this model will be related to a table named ‘users’ in my database. I don’t need to define this in a configuration file or something. A model is, by default, related to a table with the same name in plural  form and lowercase.
 
And since we are talking about a table in a database, my database itself will ‘automagically’ receive the name of my application, followed by _test, _development and _production, depending on the environment I’m using.
 
Even before that… when I decided to create the model User by myself, not using ‘rails generate model’, I put my user.rb file, with the model code, inside app/models directory. Why? Because it is there that Rails will look for it by default!
 
Default is the great word here. Convention over configuration means, stating it in a simple way, that Rails framework has lots of defaults. Defaults for almost everything.
 
Convention helps us a lot, because it allows us to concentrate where we need: in the complexity of our system, not in the ‘housekeeping’ of it. We are paid to develop valuable software, not to spend time deciding where this or that file must be.
 
So, my advice is “Do NOT change conventions without good reason”. And I mean a REALLY good reason.
 
Going back to the tables stuff… One may change the name of a table associated with a model using set_table_name. But why would you do that? Let’s examine some explanations people usually give:
 
  • I am converting a legacy system to Rails and the table already has a different name. Great. Then rename it. Besides, if a table containing users is called ‘potatoes’, for instance, then there is some problem with the modelling of this legacy system, or with the mind of the person who named it.
  • I am converting a legacy system to Rails and the table I’m working with contains users, but also other data. Then again you have a problem in your modelling and since you are refactoring the system to convert it, it’s exactly the time to change this. You have no problem that a new table to separate this data and a foreign key won’t solve.
  • I am starting a new system from scratch, but Rails conventions are an obstacle to my creativity and I want to call the table of users by another name. You are an asshole! A big asshole! Forget programming and go to fine arts. Painting, maybe. There you may express your creativity without bothering people.


What would be the advantage of calling a list of users by another name? One of the most basic problems this would cause would be the fact that rational people (and we expect programmers are rational…) will take some time to understand your “creativity” and realize that table named ‘potatoes’ contains, in fact, a list of users. If you use this kind of “creativity” a lot, in the end your system will be a complete mess and the level of maintainability will be very low.
 
Rails conventions were created to make things easier. Do not change them if you can avoid the change. And if you can’t avoid the change, at least document it very well.
 
In my next article I’ll discuss things that may sometimes (and in fact sometimes need) to be changed.
 
 
 
 

Tuesday, January 19, 2016

Some rules to gather a great development team



I know, I know... This blog is about Ruby and Ruby on Rails, right?

Yes, but... sometimes when interesting subjects come to my mind I feel the compulsion to write about other things.

This question appeared while I was chatting and having some beers with some buddy programmers, developers, tech leaders and project managers. Of course such a chat cannot stay away from working things for too long and someone raised this question, which floated among us as an uncaptured exception for a while.

Of course any of us had a well-defined set of ideas about this subject, but the discussion went for a while without any conclusion. Our ideas were far too different to be united in a single set of principles!

What you will read here is a subset of my own ideas, more a few things I picked up amomg my friend's ideas. Not an exhaustive set, of course.



1) Find enthusiastic people. Great programmers are generally people capable of celebrating with shouts and dances when a particularly difficult piece of software works as expected. This rules has exceptions, of course, and I met two or three icemen during my 31-years-old career, great programmers capable of facing success in a hard software task without even a smile. But the rule still applies. Enthusiastic people are always seeking success. And success for them is success for your project, if you are smart enough to engage them sincerely in what they are doing.

2) Find those "ethernal students". It is not important if he or she knows the language or the framework your project will be using. I've been into this time enough to tell you that learning new languages is an easy taks if you already know one of them and has the mind of an "ethernal student". And I don't mean those who just learn new things when necessary, but those who love doing so. Those who ask for tasks leading to new knowledges. Those are the guys and girls I'm talking about. You know them. If you are a great programmer yourself, then you are probably one of them. If you reached a top tech position, you surely are one of them.

3) Find people capable of disagreeing in a healthy manner. This is difficult, but you must try hard, because it is quite necessary. Working as a team is not easy. Differences will appear soon. People will disagree in many things, specially in a longer project. It is vital for the team that all members are capable of listening to opposite ideas without getting and axe and start cutting people like maniacs. A great way to detect rational and soft disagreeing people is disagreeing with them right in the interview and watch their reactions. If the person picks an axe, run and don't hire. If you scape, of course! Some say finding people like this is almost impossible, due to rule #1 above. In fact, there is just a thin line between "enthusiastic" and "maniac". You'll discover this easily if you say "I prefer emacs" to a VI user, or "Windows is a great platform" to a Linux addict. So, good luck and remember no to let axes close to your cadidates.

4) Find at least one person thinking differently from the rest of the team. This is one of the reasons why rule #3 is necessary. If, for instance, most of your team already told you they love DDD and Anaemic Domain Model, hire a guy/girl which is a critic of these patterns (or anti-patterns, as you like). It's always good to have someone thinking differently of the rest of the group. He or she will help you to detect failures in the general thinking. It will be a great inner censorship, you may be sure.

5) Don't give much attention to academic degrees, but to what people already did. Most of the great programmers I've met during the last 31 years were school or college dropouts. And some of the weakest had PhDs. This is not a rule, of course. You'll surely find PhDs which are also great programmers. And school or college dropouts which are nothing more than unadjusted personalities or complete failures. But this is not the point. The point is that academic degrees are not decisive factors to be a great programmer. So, don't push this point too much when you are selecting people, ou you'll risk losing great people by doing so.

6) Be sure they really did what they say they did. A personal experience led me to this rule. I was selecting a team to a very complex project and one guy appeared with a long list of projects in which he, supposedly, had taken a key role. I hired him and in two weeks I noticed he had done nothing good in his whole live. In fact, he barely knew how to write C code, which was a "must have" in this project. The only thing he knew, in fact, was personal marketing. We all met people like him. In school he must have been that guy who does nothing in group tasks but is smart enough to show the results in front of an audience and gets most of the credits for this, while other people worked hard. And he was very persuasive and with a great programming vocabulary! From this occasion on I decided I would only hire people whose work I already knew or capable of doing somenthing right-here-and-now for me to see.

7) Find a great leader. A great leader is not necessarily a great programmer, but someone capable of motivating people. And this requires from us some self-criticism. If you find out your are not a great leader, give this task to someone else and just manage things at a distance. Right there on the field of action, when bits ans bytes are flowing from programmers fingertips, you need someone capable of raising the morals of the group and keep people working hard even when they are exhausted. A person capable of doing those speeches before the battle, speeches strong enough to send people to certain death with a smile in their faces. Find someone like this and your project is half-way to success.

8) Keep this leader away from programming! As I said before, this person needs not to be a great programmer. His task is not this and to mantain the respect of the team for him/her you should keep this person away from programming. If you name someone a tech leader, this person must be great in both things. A rare type, I must say.

9) Give them freedom enough, but not too much freedom. If you create too many rules at work, good programmers will spend a lot of their time trying to break them. You say Facebook is forbidden and they will take time to find a proxy server to use Facebook anyway, even if they don't like Facebook. This is not the point. Breaking the rules is the point. So, if you give your team freedom enough they won't spend much time to search for it. Believe me, programmers do not accept restrictions easily and the sooner you learn this the better. But... never leave them completely at their will. Be close and oversee their results. Because programmers tend to do useless things if they are not monitored. They will use some of the time you paid them to finish the website someone hired them to do on the weekends. They will use some time to work on a free software project they are engaged. They will write articles to their tech blogs. How much you must allow of these things is your business, not mine. But if you do not keep an eye on things, they will soon get out of control and your project will suffer as a whole.

10) Use the Force! Try to use your feelings, young padawan! Do not conform to any set of rules, including this one here. Feel your environment, try people around you, know the people working with you. Most of the problems you will face may be solved by some talk and some actions. And if you do not gather a ready-made great programming team, you may certainly try to turn the team you have now into one. It will take time. It will take effort. But it will pay if you succeed.

Wednesday, January 6, 2016

Rendering and the DRY principle



Imagine you want to render this piece of code as a partial view

<ul class="nav navbar-nav navbar-right">
  <li>
    <a href="/user/dashboard">Dashboard</a>
  </li>
  <li>
    <a href="/user/profile">Profile</a>
  </li>
  <li>
    <a href="/user/courses">Courses</a>
  </li>
  <li>
    <a href="/user/schedules">Schedules</a>
  </li>
  <li>
    <a href="/user/invoices">Invoices</a>
  </li>
  <li>
    <a href="/user/tickets">Tickets</a>
  </li>
</ul>

Then you put it in app/views/users/_menu.html.erb and inside app/views/users/view_one.html.erb you put something like

<%= render 'menu' %>

This works perfectly well, of course, and the menu will show up exactly where you want it to. 

But now, imagine another situation. You want to show this very same menu in a view of another controller, let us say app/views/customers/view_two.html.erb.

In Rails, partials are relative to the path where the controller has its views. Convention, not configuration, remember?

So, if you simply put 

<%= render 'menu' %> 

somewhere inside app/views/customers/view_two.html.erb, you'll get an error. The partial _menu won't be found in the scope of the views of Customers controller.

One may, of course, just issue the command

$ cp app/views/users/_menu.html.erb app/views/customers

and then the error will be gone. But then, what about the DRY principle?

Don't Repeat Yourself (DRY) is one of the principles guiding Ruby on Rails and violating it is not a good idea, for many reasons. Code repetition makes systems hard to mantain, among other things. You may read a bit more about this in 3 Key Software Principles You Must Understand.

The situation described is a problem, of course, but I have good news! You don't need to violate the DRY principle.


All you have to do is change a little bit your app/views/customers/view_two.html.erb file. Instead of 

<%= render 'menu' %>

you just need to write

<%= render 'users/menu' %>

and Rails rendering engine will look for the partial inside the correct directory!

But be careful with one thing.

When one sees such an easy way to deal with this problem, a malicious idea comes do mind: putting things to be repeated here and there inside a special directory like app/views/commons or something like that.

This is not a good idea. If you do so, there is a great risk of ending up with lots of loose code, not belonging to any of the entities of your system.







Friday, January 1, 2016

How to debug a seeding error



This happened to me right now: http://stackoverflow.com/questions/34554968/type-mismatch-when-seeding-database

I was seeding a database for a web application when I started getting this error: ActiveRecord::AssociationTypeMismatch: Role(#97332160) expected,
got Fixnum(#76482890)

This means I was tying to force a Fixnum into a Role object. But this wasn't the case. Or at least so I thought...

Here are the definitions of the tables I was trying to seed.

  create_table "roles", force: :cascade do |t|
    t.string   "role",       limit: 50, null: false
    t.datetime "created_at",            null: false
    t.datetime "updated_at",            null: false
  end

  create_table "users", force: :cascade do |t|
    t.integer  "role_id",    limit: 11
    t.string   "first_name", limit: 100, null: false
    t.string   "surname",    limit: 100, null: false
    t.string   "email",      limit: 255
    t.string   "password",   limit: 150
    t.datetime "created_at",             null: false
    t.datetime "updated_at",             null: false
  end

  add_index "users", ["first_name"], name: "index_users_on_first_name", using: :btree
  add_index "users", ["role_id"], name: "index_users_on_role_id", using: :btree
  add_index "users", ["surname"], name: "index_users_on_surname", using: :btree

  add_foreign_key "users", "roles"

And here are my seeds.rb commands:

rl = Role.create(role: "root")
User.create(first_name: "Edvaldo", surname: "Silva de Almeida Júnior", email: "xxxxxxxxxxxxx", role_id: rl.id, password: "xxxxxxxxxxxxx")

rl = Role.create(role: "admin")
User.create(first_name: "Daiely", surname: "Fanchin", email: "xxxxxxxxxxxxx", role_id: rl.id, password: "xxxxxxxxxxxxx")

rl = Role.create(role: "user")
User.create(first_name: "César", surname: "Silva", email: "xxxxxxxxxxxxx", role_id: rl.id, password: "xxxxxxxxxxxxx")

As you may see, I was doing no wrong, at least at first sight. The only point in my seeding which could go wrong was role_id: rl.id and this wasn't wrong ar all. I wasn't forcing a Fixnum into a Role. I was forcing a Fixnum into a numeric field.

This is the kind of error which may be confusing to debug. You keep looking to what you did right and forget to look what you did wrong, which may be masked somewhere else. Exactly what I did and it took me two hours and a question posted ad StackOverflow to remember a very important truth.

Seeding is not just forcing data inside a database. Seeding makes ActiveRecord evaluate completely the models involved. Then, your error may be anywhere inside your models and then checking your methods is necessary. 

Exactly what happened to me in this particular case.

This was my User model:

class User < ActiveRecord::Base

  has_one :role
  after_initialize :set_default_role, :if => :new_record?

  def set_default_role
    if User.count == 0
      self.role ||= 1
    else
      self.role ||= 2
    end
  end

end

As you may see, I was trying to initialize sel.role with numerial values, indeed! Exactly what ActiveRecord told I was doing!

As soon as I rewrote this set_default_role method to

  def set_default_role
    if User.count == 0
      self.role_id ||= 1
    else
      self.role_id ||= 2
    end
  end

everything worked fine.

The suggestion, then, is: Whenever you have a seeding error, check the models involved, not just the values you are seeding.