Book Review: Crafting Rails 4 Applications
Crafting Rails 4 Applications is a great book to:
- Learn how to write a Rails plugin
- Learn some interesting history of Rails (like
- 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:
- Add specific formats renderer to
ActiveModel::Modelto build an
prepend_view_pathto add custom view resolver to get view templates from other sources (like database)
- Inherit from
ActionController::Metalto build a thin controller
ActionView::Template.register_template_handlerto add template handler for parsing view templates
- Add custom Generator to generate code from a custom template
Rails::Railtieto configure your plugin
- Add plugin's own controllers, models, helpers, etc., by inheriting from
- How Rails eager loads the code
ActiveSupport::Notificationsto publish/subscribe to an event
- What is Rack, Rack Middleware, and how to write a middleware
- Add a new I18n backend (to use Redis as the data store)
What can we learn from them
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.
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::Modelis used by
ActiveRecordheavily since it was extracted from
ActiveRecordalike functionalities for other Ruby classes.
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 (
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
- Respond to PUT/PATCH API request with :ok by claudiob · Pull Request #12136 · rails/rails
- Move respond_with to the responders gem · rails/rails@ee77770
- plataformatec/responders: A set of Rails responders to dry up your application
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.
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).
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.
- Use some server-client events system to connect frontend/backend
- Use some file system plugin to detect file changes
- 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)
- 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:
- All the middlewares only need to be compatible with a pretty simple API
- Almost anything can become a middleware thanks to the simple API
- Controller Actions
- A Rails/Sinatra Applications
- 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 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
before_action) and the
Plug pipeline abstraction is more natural
and easier to understand.
It's a great book to start learning some intermediate Rails techniques, even
with some outdated contents like
And what's more interesting? Connecting the dots between Rails and Phoenix in this book.