Book Review: Crafting Rails 4 Applications
TL;DR
Crafting Rails 4 Applications is a great book to:
- Learn how to write a Rails plugin
- Learn some interesting history of Rails (like
responder
) - 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
ActionController::Renderers
- Include
ActiveModel::Model
to build anActiveRecord
alike object - Use
prepend_view_path
to add custom view resolver to get view templates from other sources (like database) - Inherit from
ActionController::Metal
to build a thin controller - Use
ActionView::Template.register_template_handler
to add template handler for parsing view templates - Add custom Generator to generate code from a custom template
- Include
Rails::Railtie
to configure your plugin - Add plugin's own controllers, models, helpers, etc., by inheriting from
Rails::Engine
- How Rails eager loads the code
- How
responder
works - Use
ActiveSupport::Notifications
to 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_master
1). 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::Model
is used byActiveRecord
heavily since it was extracted fromActiveRecord
for providingActiveRecord
alike 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 (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:
- 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.
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.
- 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
- Rack
- Controller Actions
- A Rails/Sinatra Applications
- Phoenix
- Router
- Controller
- View
- Rack
- 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.