How to Send Data to Partials to Generate Custom Behavior in Rails 5
In addition to partials allowing applications to share view code, Rails also makes it possible to send data to partials in order to give them custom behavior. In this guide we'll examine how we can use locals in partials to refactor the Portfolio form and to add dynamic styles to the navigation bar.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

In the last guide, we implemented partials in our layouts. We created a shared directory and implemented the nav component shared it across our application layout file, blog layout file and our portfolio. We can actually extend this further. We're simply calling a partial just by itself.

We actually have the ability to pass in data. We're going to create kind of an easy implementation on this first and then we're going to extend it into our form for our portfolio. If we look at our form for blogs you can see that blog is called right here. This is passed in as a variable, you may notice it's not an instance variable. It's technically not being called directly from the controller. Remember how data flow works, the controller actions pass data to the views via instance variables. Whenever you're using partials you can actually pass in, because there is no form action inside the blogs controller there is a new and an edit. The way that it works from a data flow perspective, if I open up blogs controller and let's say just for a case study looking at the new action, we create a new instance of a blog and we store it in an instance variable. From here, this is passed to the new template. Here it's passed in and this is called a local, you can pass partials locals. What happens is this blog instance variable now gets transferred into this local blog variable. Inside of the form partial this blog here and here and here, this is actually just a local variable that's being passed in via the new partial call or the edit partial call wherever it's being passed in.

Let's talk about how we can now transfer that knowledge and what we can do with our nav and then we'll go in the portfolio. One thing that I do for instances like this is I want to have a specific set of items such as styles for different nav components, this is a nav for a portfolio, this is for blog and this is for the application. It's more likely than not because these are all different layout files, I want different styles associated with the nav component. Because this is shared then we're kind of stuck right? Not technically, we can actually make this dynamic and I'm going to show how we can do that here.

I'm going to say div class and inside of this is where we can use some embedded Ruby. I can say here location which is just that's just a variable name, this is our local, the same way that the blog form partial had blog, we're going to create a local variable and we're going to pass data into it so that it can be used by our nav component.

I'm going to copy location and come to our application.html.erb and now I can give a comma after the render call say location and then here I going to say top.

Now I just will copy this, come to blog.html.erb and say bottom and there's nothing special about this what I'm essentially doing is I am creating CSS classes, not going to get into this really until our style section. But I think that this is a pretty low-level introduction to it. And we're going to be able to create dynamic styles for our partial based off of doing this. If some of this seems a little bit fuzzy just hold on and I think you'll be able to see when we actually implement this what it's doing.

We have our same render call so we are calling the same exact partial. The only difference is now we're passing in a local variable and we're passing it in and it's called location, in application layout file it's called top, blog I'm calling it bottom and then for portfolio I'm calling it top.

Now the other thing that we can do is if I scroll up and open up our respective CSS files now I can use those CSS classes. Portfolios was top, if you never use CSS before, I'm saying that I want to apply styles to any components that have that class top and that are a link. And that's what that A stands for.

You're just going to say color and red the very basic this is going to be really ugly but it's going to show the difference.

large

For blog, we also are using the bottom class so I want to select that as white because blog has that kind of charcoal gray color.

large

I believe this is everything that we're going to need and I have the rails server running. If I come into chrome and hit refresh. Look at this, our new styles are being used on the application layout file. These are the brown styles so everything is good. Now if I click on blog and scroll all the way down, now these elements are white and then if I click on portfolio then these links are red.

This is giving us exactly the behavior that we want. Now, not only are we able to share code but now our implementation is much more flexible since all of these are completely different layouts they're going to have their own unique look and feel. By implementing this type of partial implementation now we can pass our own customizations.

In other words, when we're passing this render shared nav we can say this is a special thing where I want to pass it in and I want to add a class of top to the shared nav. Whereas when we call it from the blog layout I want to add a class of bottom and then the CSS styles can just dynamically change the look and feel of the application. That is how you can use locals.

Let's kind of extend this knowledge now and be able to implement a partial for our portfolio. I'm going to close each one of those out and now I'm going to come to our portfolios, create a new file going to say _underscore.html.erb. If I go to New I'm going to copy all of this over and in New. Now I'm just going to say here render and form and we need to pass in a portfolio item and that's going to be taken from the portfolio item instance variable.

large

just like our blog controller and form partial we're doing the same thing here where we're passing in data that the form can use.

Now one item here that is a little bit different is let's take a look at our new form.

large

right here we have fields for technologies where we're getting our various technology forms. I'm going to be interested to see if this works or not because I haven't run through this beforehand because if I run into any errors I want you to see them so that we can figure them out together.

Now I'm going to copy this and we can do the same thing for edit. Come here delete all of this and hit save.

large

And now we can go check it out.

OK let's go to our portfolio and then we can click on Create new item and looks like it's working. Let's test it out and see if this is working here. Create portfolio, everything there works.

Now if I want to edit an item so if I click edit, our update action is showing but also notice that none of those fields are showing. why is that? I think that we should be able to fix that relatively easily. Let's open up our portfolio controller, inside of our new action, we have this 3 times portfolio item technologies build. Our edit action would need that as well. Now there is one thing that I'm not going to fully implement right here, not because I don't think it's a good idea but more because there's no point in it because we're eventually going to make this a javascript implementation.

Just so you can see exactly how this will work. Let's come here put it in the edit action hit save and now hit refresh and you can see that now we have our items here. And if I hit update portfolio everything works, if I come back and click Edit you can see that it has these but it's also still rendering three new ones so that's not exactly the type of behavior that we're looking for. If I scroll all the way down and click edit, you can see that it's showing them but it's still not exactly we're looking for. Let me come here and if I get rid of this and save, now this is working a little bit better.

There are still a few little bugs in there. And the reason is that all of these items are hard coded from an HTML standpoint. I wanted to kind of go through this so you can see why this would not be the best solution in a professional environment and why javascript is required.

Technically you could build out an implementation like this but it's going to be very static. It's kind of the way that we would have built apps about 10-15 years ago where you hard code these values in, in terms of you know how many form fields are here. In modern times you're used to having something like this where you can have a little button here and click new form new form new form element and then you can have new ones generated dynamically instead of us trying to guess, "OK, do we want to have extra form items here and in the edit action and do we want three new ones here? That's just not a very intuitive way of building it. That is the reason why javascript's required.

I wanted to show you this example because if we went straight into the javascript example then you may not appreciate why it's so important. I wanted you to see that this works and everything processes, if I type something in and hit update portfolio all of that works. And if we come down and you take a look at the portfolio item you can see that these have all been added and everything is working but we can do better and we will when we get to the forms section and we can implement javascript and make it a little more dynamic.

The purpose of this guide was to focus on partials and I think that we did a very nice job here. We have a completely new portfolio item and there is one little tiny bug with this, if you come to create a new item, Notice how it says create a new portfolio twice. It's because this partial still contains that header values, I'm going to delete that. It's only the form that's contained inside the form partial, new is only establishing the header then it's calling the partial It's providing the data for the portfolio item and edit is doing the same thing. Hit refresh, it fixed that and everything is still working. Hopefully, you can kind of appreciate how much better this is then when we had the two almost identical forms because remember how our edit action form didn't even contain any of our technology fields. Now just by calling the partial, we have access to that we can still make it better but at least we have access to it and we don't have to have duplicate code in the application.

  • git status
  • git add .
  • git commit -m "Implemented partials with local data for portfolio form and nav bars"
  • git push origin view

In the next guide, we're going to start getting into how we can integrate view helpers. [

Resources