Book Review: Crafting Rails 4 Applications

TL;DR

Crafting Rails 4 Applications is a great book to:

  1. Learn how to write a Rails plugin
  2. Learn some interesting history of Rails (like responder)
  3. Learn how Rails affect other web frameworks (especially Phoenix)

But it might not be a good book to learn how to write a better rails application nowadays.

Rails plugin techniques

In this book, José Valim introduced several techniques to write a Rails plugin:

  1. Add specific formats renderer to ActionController::Renderers
  2. Include ActiveModel::Model to build an ActiveRecord alike object
  3. Use prepend_view_path to add custom view resolver to get view templates from other sources (like database)
  4. Inherit from ActionController::Metal to build a thin controller
  5. Use ActionView::Template.register_template_handler to add template handler for parsing view templates
  6. Add custom Generator to generate code from a custom template
  7. Include Rails::Railtie to configure your plugin
  8. Add plugin's own controllers, models, helpers, etc., by inheriting from Rails::Engine
  9. How Rails eager loads the code
  10. How responder works
  11. Use ActiveSupport::Notifications to publish/subscribe to an event
  12. What is Rack, Rack Middleware, and how to write a middleware
  13. Add a new I18n backend (to use Redis as the data store)

What can we learn from them

  1. How to write a Gem works for Rails applications

    If we want to write a Gem for Rails (something like wulin_master1). These techniques are pretty useful and we definitely need them.

  2. A good start point to learn Rails structure

    Some of these techniques are not only useful for writing Rails plugins, but also used in the internal structure of Rails. For example, ActiveModel::Model is used by ActiveRecord heavily since it was extracted from ActiveRecord for providing ActiveRecord alike functionalities for other Ruby classes.

  3. Rails is not only a great framework for writing applications, but also a great framework for writing plugins

    With all these techniques, writing a Rails plugin is almost as easy as writing a Rails application. No wonder that we have so many Rails related gems in the community and Rails programmers always want to solve their problems by installing a gem (which is quite controversial).

Tests are important, even for plugins

Another thing that I found interesting was that José used TDD for all the plugins in this book.

Thanks to the Rails framework, testing a plugin is just as easy as testing an Rails application. You just need to create a dummy app and use your plugin in this app, then you can write tests for this app to test your plugin's behaviors.

The history of responder (respond_with)

When I started learning Rails, Rails 5 was already out. So, I was confused when I saw some calls to respond_with in some Rails 4 applications (since I could not find it in the latest doc and found it was deprecated.)

This book has a full chapter about the idea behind responder and how it works.

This is how/when respond_with got removed from Rails 4.2 and moved into the responder gem:

I totally agree with this removal. Because respond_with made the controller actions harder to read/extend. It's totally unclear to a new developer how a response gets rendered and how different formats are treated differently.

I guess even in a convention-over-configuration framework like Rails, we still need some explicity sometimes.

Things that remind me of Phoenix

Since José is also the creator of Elixir and one of the maintainers of Phoenix, I found many ideas from this book that remind me of some similar ideas from Phoenix.

These similarities might be a natural results due to that Phoenix is a Rails-like framework in the Elixir world, and the creator of Phoenix (Chris McCord) has a strong Rails background.

But it's still interesting to compare these similarities and see how they are useful in both worlds.

Customizable Generators

Phoenix also has the ability to customize the generators. Just create some templates files under the priv/templates directory and use the same folder structure as the default structure2.

But Phoenix won't allow dependencies to overwrite default templates3. Because Phoenix always prefers explicitness over implicitness. All the custom templates are under priv/templates directory so that users won't need to dive into the application dependencies to see which line is generated by which dependency (they have full control what will get generated and what won't).

Live-Reloading

It's really interesting because when I read the chapter about assets live-reloading, I think this is the same idea behind Phoenix's assets live reloading.

  1. Use some server-client events system to connect frontend/backend
  2. Use some file system plugin to detect file changes
  3. Use a separated thread to run file system watcher (in Phoenix is an Elixir thread, in Rails is a Ruby Thread which simulates the Actor model in Elixir)
  4. Send a notification to client side that some files had changed, and client side updates the page

The only difference between the Phoenix implementation and the implementation from this book is that

  • Phoenix uses WebSocket
  • This book uses Server Sent Events (SSE)

Rack and Plug

When I read about Plug in Programming Phoenix4, I immediately recognized that it's just like Rack. These are things that make them very alike:

  1. All the middlewares only need to be compatible with a pretty simple API
  2. Almost anything can become a middleware thanks to the simple API
    • Rack
      • Controller Actions
      • A Rails/Sinatra Applications
    • Phoenix
      • Router
      • Controller
      • View
  3. Middlewares can be easily composed together to build a pipeline

But I feel that Plug is taking this abstraction to the next level because its API specification is much simpler (Plug.Conn in, Plug.Conn out) than Rack (env in, a 3-elements Array out). And with this more powerful abstraction, many things in the Phoenix world can be expressed in the Plug way (especially things like before_action) and the Plug pipeline abstraction is more natural and easier to understand.

Summary

It's a great book to start learning some intermediate Rails techniques, even with some outdated contents like responder.

And what's more interesting? Connecting the dots between Rails and Phoenix in this book.