loading...

Comparing Rails and Lucky: Partials

edwardloveall profile image Edward Loveall ・3 min read

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.

Discussion

pic
Editor guide
Collapse
nhh profile image
Niklas

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

Collapse
edwardloveall profile image
Edward Loveall Author

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!

Collapse
nhh profile image
Niklas

Very nice DSL! Why there is nothing equal in Ruby?

Thread Thread
edwardloveall profile image
Edward Loveall Author

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.