Posts by Lucas Mazza

Rails 4.1 was just released this week and I already had a great experience trying out the release candidates on my latest project, so I decided to write a bit about my favorites features on this release and some things I have learned by using them so far.

1) secrets.yml

Placing your configuration in a YAML file isn’t exactly a revolutionary feature, but the usage of the config/secrets.yml file that comes with Rails 4.1 holds a more important idea: the promise of a default approach for environment aware custom configuration on Rails applications. Over the years the community created several ways to manage such configuration so every app out there deals with this differently, but now we can use the Rails default as a standard just like we do with the app folder or the routing patterns, taking the configuration madness outside the list of things to worry about when working with Rails. So instead of dealing with multiple YAML files or constants left out inside initializers, we can go with the secrets.yml as the default for our apps.

Remember that you can place any kind of configuration – not just secrets like tokens or passwords – that need to be handled differently through your application environments, like API Endpoints or S3 bucket names. And for any gem maintainers out there, you can make your gem read these settings from the secrets.yml automagically through an initializer block and maybe remove a configuration step from the gem setup. Adding this to Devise on this pull request was easier than I expected an I suggest you to try it out on your gems as well.

If you want to try to organize your configuration through the secrets.yml without having to update to Rails 4.1 right now, Andrew White backported this feature on the rails-secrets gem for Rails 4.0 apps.

So, if you are dealing with some configuration mess or aren’t using something like dotenv for your application, I strongly suggest that you try to migrate your config to use the secrets.yml file and see how it goes for your application.

2) Action Pack Variants

Variants are proving to be a great solution to render device specific views when mixed with any device detection solution like the useragent or browser gems, which you integrate quickly with just a before_action block:

class ApplicationController < ActionController::Base
  before_action :set_variant
 
  private
 
  def set_variant
    if browser.tablet?
      request.variant = :tablet
    elsif browser.mobile?
      request.variant = :mobile
    else
      request.variant = :desktop
    end
  end
end

Even though the main examples are dealing with User Agent sniffing, this feature can be used in any context where you want to have more control of which views are rendered by your application, like:

  • A/B Testing different partials based on the user cookies.
  • API versioning for your Jbuilder templates.
  • Maintaining current and redesigned views for the same controller.
  • Authorization aware views, like users/index.html+admin.erb or products/show.html+guest.erb.

In the end, Variants are just a way for you to have more control over how your views will be used by the app, helping you to remove boilerplate logic from your code and letting the framework handle it through a more elegant solution.

3) The improved cookies serializer

The changes on how Rails serializes cookies are a great improvement when it comes to security and stability of web apps. Before this, any object placed in the cookies Hash would be serialized (and deserialized) through Marshal.dump and Marshal.load, which could possibly lead to remote code execution if an attacker got hold on your application secret.

Now this serializer is configurable through the config.action_dispatch.cookies_serializer configuration option, and new apps will ship with a smarter default: a JSON serializer that won’t recreate complex objects besides Strings, Integers and other JSON data types. And for a smooth upgrade, you can use the :hybrid serializer that will convert your existing marshalled cookies into JSON cookies, so this upgrade can be transparent for your application users.

This upgrade highlights a possible bad practice in our applications where we end up placing more complex objects in the session that can’t be completely restored by the JSON serializer, when we should be using more simple structures for the data stored in cookies. Thanks to a related issue reported on the Devise issue tracker we could simplify the gem code a bit, so instead of serializing Time objects we could work with numbers.

So, when updating your application to use the :hybrid serializer, don’t forget to do a double check of whatever kind of data the app stores in your users cookies and look for possible backwards incompatibility. And if you want to take a closer look on how this was implemented, be sure to check the related issues and pull requests on the Rails repo: #12881, #13692 and #13945.

Keeping up to date with the latest Rails changes

Following the activity on the Rails repository over GitHub helped a lot to understand better these features and the rationale behind their implementations, but going through all the commits and discussions on Issues and Pull Requests would demand a lot of your time. If you want some of the inside scoop but don’t have that much time to go through the Rails activity over the week, Godfrey Chan has put up a weekly digest about Rails named This Week in Rails. I suggest that you subscribe to the list and even check some of the previous editions on the archive page.

Try it yourself!

Take some time and upgrade one of your Rails 4 apps and try out some of the new features! I bet that some of them will help you improve your codebase or make your coworkers life a bit easier, and we are eager to hear from your experience with the 4.1 release.

July and August of 2013 will be a mark in the Plataformatec history as the time when we moved out from our green house in the Vila Madalena neighbourhood to a brand new office in the region of the Paulista Avenue.

The brand new Plataformatec HQ 2.0

The brand new Plataformatec HQ 2.0

Our company has grown a lot in this year (we are about to pass the number of 20 developers in our team, can you believe it?) and our office wasn’t enough to accommodate the entire company anymore. So we have been out in the city looking for a new house for us. We took our time to pick a new place for us to call of ‘Headquarters’, that wasn’t an easy task to do. We chose a beautiful and charming antique house, but since it is almost 100 years old, it needed to go through a lot of repairs and improvements to accommodate the Plataformatec team.

So, while we are in between places, some of our teams are working remotely across different places in the city as we wait for our new office to be ready. But thanks to our heavy usage of asynchronous communication channels our productivity looks the same as before. We use tools like Basecamp, GitHub, Skype and Campfire to get our things done and talk about our projects – from like code reviews to scope related discussions and everything else – without getting in the way of anyone who might be busy with something else, so when we end up working apart it isn’t such a big deal since we are used to communicate and work in some sort of remote way.

But while some developers would jump out of happiness for the chance of working from homes, I miss that good old office that I used to commute to everyday, because I don’t go to work to work.

In all these months at Plataformatec the office has proven to be much more than a place to write code and do our work. It became a place to share our stories, to improve our craft, to build our projects together and to have fun with our friends. So working from home without the whole “HQ Experience” isn’t quite the same thing for me and some of the others members of our team.

Our first tour in the new Headquarters.

Our first tour in the new Headquarters

All of the effort we have put into developing and maintaining our culture and values has reflected in a work environment completely different from any average consulting office, and as the company grows and we improve our values we hold the responsibility to keep improving our HQ for everyone who is or will be part of the company.

We couldn’t be more thrilled about this. I would like to thank everyone who have been cheering and following our work, and we would love to share our excitement with this new chapter in the history of Plataformatec. Be sure that we are going to post and tweet a truckload of pictures and videos as we move in to our new HQ. Let these new chapter be as great as our history have been.

We have a gem available for every kind of feature or scenario we might face in our applications and that may help us focus our development time on things that are more important to our applications. But, every now and then, these packaged solutions aren’t exactly what we need, and some sort of customization needs to be done on top of that – a different authentication strategy, new ways to query for data and several different things that our business rules might require.

So, we jump on top of the existing code to bend it to our needs but sometimes things can go south and we end up in a mess of hacks, unstable code and bad experiences. After some time, we started to develop a few guidelines of our own to avoid the mistakes of the past and look forward to write better applications. These are some of the ideas that I follow to avoid complications when dealing with 3rd party code:

Don’t fear the source

The source code and its documentation are your best friends on this. Having a local clone of a dependency repository lets you ack/grep it inside out to see how the code is structured to identify the good and bad parts to mess with. You can test your changes against its test suite to see if you might break something or not and that’s already one step closer to contribute back to the project.

Respect method visibility

Method visibility is an important tool to ensure that you aren’t messing with the wrong pieces of code from a gem. Public and protected methods are meant to be overriden when necessary, but private ones aren’t. They are usually doing the work that you don’t want the trouble to do it yourself, and maybe that’s why you are using the dependency after all.

For example, ActiveRecord adds a lot of private methods to handle the persistence of your models that you shouldn’t mess with, but the public API is stable enough for you to use it for whatever you need.

Monkey patch at your own peril

Ruby lets you monkey patch everything but that doesn’t mean you should. While this might make a lot of sense for libraries that extend the Ruby stdlib (like ActiveSupport), monkey patching someone else constant might bite you back later. Overusing monkey patches might be a serious block when updating your application to newer versions of a big dependency of your project (for example, Rails).

When you monkey patch, you are usually messing with a very internal piece of a component that might be far from it’s public API. So, you can’t predict how that class or module will behave when a new version is released or what other parts of the code are using that internal API. Classes get renamed and refactored everyday, and it’s hard to ensure your patches will keep up with those changes.

Composition (and inheritance) as extension mechanisms

A lot of gems provide a series of configuration options that you can drop in an initializer and get the behavior you need, or maybe a specific configuration might be missing. You might feel the urge to send a pull request adding a new configuration to the project, but hold that idea for a second. Can’t you do it by overriding a method or using a custom component of your own?

Inheritance and composition can be a better choice for a lot of customizations since they are easier to test and to isolate the effects on your application. While a configuration setting is global and affects your entire application, an isolated change will have a much smaller impact on your code.

Take for instance the to_param and to_partial_path methods from ActiveModel. You can override them in your models to change how your views will interact with them, and that goes in a per model basis, since you usually won’t do that for your entire application. Imagine if you need to change a configuration instead overriding a method: You would have to do something weird like this:

# A regular configuration inside an initializer
config.action_view.parameterize_method = :slug
 
# But what if I need a per model configuration? Well, use a Hash!
config.action_view.parameterize_methods = { post: :slug, user: :id }

While just overriding the to_param method in your Post model is a lot easier than this.

Another example of composition I came across recently was the tokenizer option on the LengthValidator. Given that you have a description column in your database that accepts HTML tags like strong and em, and you want to validate the length of the text, but not the HTML, you can provide an object that responds to call and strips away the HTML from the string, so the validation will be executed against the raw text instead of the whole HTML of it.

class MyOwnTokenizer
  def call(text)
    # do whatever you need with `text`.
  end
end
 
# on your model…
validates :description, :length { tokenizer: MyOwnTokenizer.new }

Your code, your problem

Remember to test your changes. Once you change a default behavior or tweak some specific configuration that might have side effects on other parts of your application, your test coverage will help ensure that this behavior won’t break once you update a dependency on your project.

You usually shouldn’t worry about testing library defaults (like testing the validations on your models that you configured with ActiveModel validation methods), but once you customize something, that piece of code is your responsibility.

So, if you added your own tokenizer use along with a LengthValidator on your application, be sure to write at least an unit test for it to ensure that it works as expected.

Contribute back

Sometimes you might notice (or need) an improvement to a library that won’t change anything on its public API but will make your life easier when extending it. You can’t expect that the maintainers will discover every spot that can or might be overriden, so it’s important to bring your experience on using it to the table and help others. You can extract a specific behavior to an isolated component, or improve some internal logic so it might be easier to extend it in the future. There’s nothing but love for such kind of contribution.

A while ago this pull request changed how Rails added the associations proxies to a model that is using belongs_to and friends. While it didn’t changes a single bit about the public API for the associations, it changed how you can extend them to add your specific behavior.

Wrapping Up

These steps might not fit everyone’s workflow, but we need to keep in mind that dealing with external dependencies requires a thoughtful approach to avoid the results being harmful to your projects.

And what about you, my fellow developer: how do you approach the need for something more than a gem’s default behavior? Jump on our comments thread to discuss more about it.

Aqui na Plataformatec eu trabalho lado-a-lado com desenvolvedores (back/front-end), designers e gerentes de projetos. Francamente, é difícil saber onde termina o trabalho de um e onde começa o trabalho do outro. Existe muita sobreposição de conhecimentos entre os membros das nossas equipes e isso é muito bom! Nós realmente acreditamos no poder das equipes multi-disciplinares e os nossos resultados nos convencem cada vez mais disso.

A capa do livro "HTML5 e CSS3: Domine a web do futuro"

A capa do livro “HTML5 e CSS3: Domine a web do futuro”

E a melhor evidência de que eu também acredito em multi-disciplinaridade é o meu recém lançado livro: “HTML5 e CSS3: Domine a web do futuro” publicado pela Casa do Código. Sou desenvolvedor há algum tempo e sempre me interessei por front-end. No começo eu tive dúvidas em qual assunto me aprofundar, mas entre escolher um caminho ou outro acabei optando em aprofundar em ambos. Confesso que eu não me arrependo em nada da minha escolha e estou muito contente em ter aprendido bastante ao longo do caminho e hoje eu poder compartilhar o que aprendi em HTML e CSS através deste livro.

Escrevi este livro pensando em desenvolvedores web que desejam aprimorar os seus conhecimentos em front-end e profissionais que estejam dedicando exclusivamente a estes assuntos. Aprendi muitas coisas ao ‘fazer’, por isso eu tentei replicar este tipo de aprendizado no livro com vários tutoriais e lições sobre técnicas clássicas de CSS e HTML (utilizando float, pseudo elementos e outros) e combinações de CSS3 para componentes visuais.

Para quem se interessar, o livro está a venda online na Casa do Código (versões impressa, .mobi, .epub e .pdf).

Plataformatec na QCon SP

Aproveito para fazer o convite para assitirem o meu lightning talk sobre CSS3 Transitions e a palestra do José Valim “Uma abordagem moderna para programação na Erlang VM: Elixir” na QCon SP, neste final de semana, no dia 04 de Agosto.

Fora a minha palestra, eu estarei no stand da Casa do Código (lá na QCon). Passe por lá para bater um papo. Será um prazer! ;)

Besides the big and shiny features that Rails 4 holds, there’s a lot of small improvements on several other sections of the Rails framework – helpers, core extensions, app configurations and more – that might not even hit the Changelogs but will somehow make our lifes easier in the future. One of these hidden gems that I’ve found recently is an improvement on the content_for helper to flush and replace previous chunks of HTML with new ones.

The content_for that we are used to

The content_for method is an old friend of every Rails developer, and it’s a pretty simple and flexible helper. You can store a chunk of HTML from a String or a block, and grab it somewhere else in your views or yield it directly into your templates. It’s a pretty handy trick to move data from your views into your layouts, like page titles, custom meta tags or specific script tags that your page needs to include.

# On your 'application.html.erb' layout, inside the '<head>' tag.
<%= yield :metatags %>
 
# Then, into a specific view
<% content_for :metatags do %>
  <meta property="og:image" content="http://example.com/image.jpg" />
<% end %>

Multiple calls of the content_for helper using the same identifier will concatenate them and output them together when you read it back on your views, as:

<% content_for :example, "This will be rendered" %>
<% content_for :example do %>
  <h1>This will be rendered too!</h1>
<% end %>

On some scenarios this behavior might not be desired, and with Rails 4 you can flush out the stored pieces of an identifier and replace it instead of adding more content to it: using the flush: true option. The first implementation used an extra true argument, but we changed to use a Hash instead, so the flush key can express better the behavior we’re expecting.

<% content_for :example, "This will be rendered" %>
<% content_for :example, flush: true do %>
  <h1>But this will override everything on the ':example' block.</h1>
<% end %>

The gallery situation

I’ve stumbled upon this on a recent project, where we had a somewhat classic scenario: a partial named _gallery, responsible for rendering the piece of HTML to display a gallery of images that also supplies a content_for block with a script tag to include the required libraries to put the gallery to work.

<section class="gallery">
  <!-- a truckload of HTML tags -->
</section>
<% content_for :scripts, javascript_include_tag('gallery') %>

It works like a charm. But with an updated requirement we had the case where multiple galleries could be present on the same page, rendering the _gallery partial several times. The required HTML would be present, but the gallery.js script would be included multiple times into the rendered page. Instead of working this out using instance variables to check that the partial was rendered at least once, we could let Rails do all the hard work for us, using the flush option when including the gallery.js script.

<section class="gallery">
  <!-- a truckload of HTML tags -->
</section>
<% # We can render this partial several times and this script will be included just once %>
<% content_for :scripts, javascript_include_tag('gallery'), flush: true %>

Back to the present: Rails 3.2

Well, while this seems to be a perfect solution to my problem, this feature isn’t available on Rails 3.2 or on the 3-2-stable branch – it’s only available on the master branch that will be released with Rails 4. But, backporting this feature into a 3.x application is pretty simple, using a helper of your own.

def single_content_for(name, content = nil, &block)
  @view_flow.set(name, ActiveSupport::SafeBuffer.new)
  content_for(name, content, &block)
end

After some source diving into the ActionPack source code we’re done – it just needs to replace any present content with a brand new SafeBuffer instance before storing the piece of HTML.

What do you think about this little addition to Rails 4? Can you think of a similar problem that could be solved with this instead of a custom hack?