You see that glEnableVertexAttribArray(0); is already there.
However when I want to render (after compiling, linking my shader), I have to use this code in order to have something rendered at my screen.

Oh, and why is it that, in your updated code, you removed the glEnableVertexAttribArray call from your initialize routine? That was correct; the enable state of an array is part of the VAO. You set it there, once, and you don't have to set it again.

It may be cleaner to unbind after using the state set by binding the VAO. But technically there is no need for it unless you want to make different state current, i.e. bind another VBO and/or index buffer (IBO) and/or different attrib arrays and/or disable/enable a different set of arrays etc. However, since to do that you'd have to simply bind another correctly set up VAO, unbinding would simply incur wasted CPU time since you'd call glBindVertexArray() twice - the first time with 0 and the next time with another VAO handle. That's one call wasted. Ok, in all fairness, if you only have 2 VAO's and don't switch multiple hundred or thousands times per frame, a few unnecessary calls won't make much of a difference.

Before GL 3.2 core there was the option to not use vertex array objects for vertex attribute submission and other stuff. In that case, unbinding a VAO actually made sense, because like with texture objects and samplers, there could be valid, usable state when no state replacing object was bound. So, if you wanted to render something that wasn't supposed to be sourced from stuff referenced by a VAO, you would unbind whatever VAO was currently bound, setup your stuff and render. However, since core GL 3.2+ mandates a VAO be active when issuing draw commands (and others) there is no way of not having a VAO bound anyway. Otherwise, you'll have the GL generate INVALID_OPERATIONs all over the place. So, nowadays with core GL, you basically never need to turn off VAOs at all - just switch them.

In general, binding VAOs is costly, as can be seen using the timelines displayed by AMD's or NVIDIA's graphics profilers (on Windows ... ). So, many VAO changes incur a significant cost and it is probably wise to limit them as much as possible. That means you put as much data into a VBO and IBO referenced by a VAO as possible and draw as many objects from a single data store as possible. You can either do so by providing correctly shifted indices and simply indicate the offset into the index buffer with glDrawElements() or you can go the easy route and use glDrawElementsBaseVertex() and similar.

Notice how I always say a vertex array object references stuff. That's because a vertex array object is just a container object containing only state, not data. The actual data is managed with the bound ARRAY_BUFFER's and ELEMENT_ARRAY_BUFFERS's data stores. This is good to know, although in single context setup it shouldn't matter to you. As soon as you're using multiple contexts, however, a VAO, like any other container object, is not shared between contexts and thus not usable from context B if it was generated and setup in context A.