Fetching models using the new Model::Find() macro
Nick Sutterer
Posted on June 27, 2024
Trailblazer comes with predefined steps we call "macros" that help you with common tasks such as validating a form object or finding an existing model using ActiveRecord (actually, any other ORM you approve of).
The newly released Model::Find()
macro is a replacement for Model()
that, over the years, turned out to be helpful but a bit hard to customize, as it wouldn't really allow you to change how things are performed in the background.
class Update < Trailblazer::Activity::Railway
step Model::Find(Song, find_by: :id, params_key: :slug)
You are going to need trailblazer-macro
2.1.16 for this goodie.
Extracting the ID
The new macro provides options such as :params_key
and :column_key
to configure how the ID is extracted. If you want to do it yourself, simply use a block.
step Model::Find(Song, find_by: :id) { |ctx, params:, **|
params[:song] && params[:song][:id]
}
A bunch of discussions with long-term users lead us to the decision that overriding ID extraction should be straight-forward since this is more than just an edge case.
Customizing the query
Once the ID is extracted, it's now very simple to customize how the query is performed (e.g. find_by: id
vs find(id)
). Nevertheless, the new key feature is the :query
option that allows you to write that code manually.
step Model::Find(
Song,
query: ->(ctx, id:, current_user:, **) { where(id: id, user: current_user) }
)
Note how the query logic can access ctx
and keyword arguments, just like a real step. The extracted ID is available in the variable :id
.
Not_found terminus
If one of the two steps weren't successful, you can instantly go to a new terminus not_found
in your business operation, indicating to the outer world that this particular step failed. With the release of trailblazer-endpoint
this will become interesting as the endpoint code could, for instance, automatically render a 404 page for you.
Discussion
The code of this macro is nothing special. In fact, it simply creates a tiny nested activity behind the scenes with two steps, one to extract the ID, and one to actually fetch the model.
Anyhow, we strongly recommend sticking with this macro instead of writing your own, for three reasons.
- Well, code we write and maintain is less work for you. Keep in mind that we also provide documentation.
- Features like the
not_found
terminus we added with forward-compatibility in mind: they will save you code once endpoints are becoming a thing. - Debugging
Model::Find()
is a matter of using our internal tracing. In the trace, you can see which part failed.
Please give us some feedback about what's missing or what you like about this simple addition to our stack. Have fun!
Posted on June 27, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024