Comparing Rails and Lucky: Partials
Tags: crystal, ruby, rails, lucky
Published: 2018-02-22 17:51:33

---
title: "Comparing Rails and Lucky: Partials"
published: true
description: 
tags: crystal, ruby, rails, lucky
---

_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:

```erb
<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](https://luckyframework.org) also has the ability to [reuse parts of a page](https://luckyframework.org/guides/rendering-html/#extract-partials-and-shared-code), 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:

```crystal
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:

```crystal
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:

```crystal
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](https://en.wikipedia.org/wiki/Type_system#Static_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.