Note: This article originally appeared here: https://blog.edwardloveall.com/comparing-rails-and-lucky-partials
If you're a Rails developer, you've likely used partials. They're a great way of splitting up a view into many reusable parts.
Consider displaying a search form:
<nav class="main">
<%= render "search" %>
</nav>
We use render
to insert a partial with the filename _search.html.erb
. In this instance, it will render an input field and a button to fetch search results. This is especially useful when we want to use this search form all over the app.
Lucky also has the ability to reuse parts of a page, but in a slightly different way. These differences make for a more streamlined and safe approach.
Lucky will generate HTML programmatically rather than with templates. For example:
def content
nav class: "main" do
h1 "My Awesome App"
link "Sign In", to: Users::New
end
end
This gets converted into HTML. It's a fresh change of pace from flipping back and forth between regular HTML and Ruby. But rendering partials is even nicer. Partials in Lucky are called Components. Here's how to use one.
In src/components/searches/search_component.cr
you would create a module:
module Searches::SearchComponent
def render_search(search_form : SearchForm)
form_for Searches::New do
text_input search_form.query
submit "Search"
end
end
end
This is the same as our _search.html.erb
partial in Rails. If we wanted to use this on a page, we can include our new module and call the render_search
method:
include Searches::SearchComponent
needs search_form : SearchForm
def content
nav class: "main" do
h1 "My Awesome App"
render_search @search_form
link "Sign In", to: Users::New
end
end
This looks a lot like rendering a partial in Rails and the result is very similar. The big difference here is Lucky is written with Crystal which uses type checking. Type checking ensures that the only way to call a method is by passing all arguments.
Our render_search
method requires a SearchForm
object. Because of type checking, there is no way to call that method unless we pass a SearchForm
.
Compare this to the Rails render
method. We can't guarantee a SearchForm
will always be available to the partial. I'll bet that anyone who has worked with Rails for a year or more has experienced this pain.
Lucky makes it impossible to forget these required objects. If we left out @search_form
above, the app won't even compile, let alone crash when running.
Put another way, to use a partial or component we need some kind of identifier. In the case of Rails, the only identifier is the file name, not the objects that are used inside of it. In the case of Lucky, it's the name of the method and the objects you pass to it, including the objects that are used inside. If you can't pass all the objects every time, the app will refuse to compile.
Of course, we can (and should!) use this technique often:
render_search(@search_form)
render_sign_in(@sign_in_form)
banner(@annoucments)
user_list(@users)
I haven't decided on the best way to name these. They could all be render
or display
and are only differentiated by their method arguments. Or maybe they're all verbose like render_search_form
. Or maybe something else! I haven't settled on the best pattern for this, yet.
One thing that comes up over and over again when working with Lucky is safety. As wonderful as Rails is, we can often find ourselves rendering a view with a nil
or incomplete object. Since Lucky has Crystal as its foundation, it's a much safer framework to work with than Rails. With safety comes benefits like fewer crashes and unwanted side-effects. But it also enables flexibility and developer confidence.
Top comments (4)
Really cool approach on rendering „engines“ i think. And what about complex views? Did you wrote some? How did that feel woth lucky?
Cheers
Niklad
I haven't had a chance to write any complex views, but so far writing views has been great. If you want to see what a complex view might look like with Lucky, I recommend trying this tool out: html2lucky.herokuapp.com
You can paste in a large HTML document and it will convert it to Lucky's DSL. I hope you enjoy!
Very nice DSL! Why there is nothing equal in Ruby?
There actually are a couple. Builder which is the basis for jbuilder in Rails, and Rumble, which is best used with Keynote. However, neither of these can make Ruby type safe. They only include an interesting DSL for writing HTML.