<%= render partial: "zebra/elephant" %>
Partials allow you to insert snippets of code into view templates to make them less bulky and incomprehensible. I'm thinking of these like old-school iframe tags in HTML but more powerful. It allows you to pull pieces of content from elsewhere to build with blocks instead of repainting each scene one by one.
<%= render partial: "movies/form", locals: { movie: @movie } %>
More powerful though is the ability to pass variables through locals to partials. In the example above, we're saying render a snippet of code with a standard form to update a Movie object in our database. Because we want to edit an existing movie we're passing it the variable movie: and sending it the @movie value. The @movie variable comes from the params hash, it's available because we're taking a route which defines @movie within the Movie controller using
@movie = Movie.find(params.fetch(:id))
So, the flow is
Route -> movies/8/edit/
goes to the routes.rb file
follows the "edit" route and passes "8" to the :id variable in the params hash.
then it runs the edit function within the movies controller...
def edit
@movie = Movie.find(params.fetch(:id))
end
which then assigns @movie an Active Record relation that matches the movie with id "8". That allows the snipped of code
<%= render partial: "movies/form", locals: { movie: @movie } %>
to use @movie when passing it to the partial that runs the form
<% movie.errors.full_messages.each do |message| %>
<p class="alert alert-danger w-50 mt-4"><%= message %></p>
<% end %>
<%= form_with model: movie do |form| %>
<div>
<%= form.label :title %>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :description %>
<%= form.text_area :description %>
</div>
<div>
<%= form.submit class: "btn-primary" %>
</div>
<% end %>
tl;dr the local variable in the template that calls in the partial must match the element within the partial you're calling to activate.
Top comments (0)