Easy Internationalization for Your Rails App with BDD, Part III
Editing A Location.
In the first part, we built an application that lists locations in English and Spanish. In the second part, we added the ability to create new locations in English and Spanish.
In this part we will edit a location, showing localization concerns along the way. Remember, we are using Cucumber and BDD to drive out our application.
Let’s write a scenario to do that.
[gist id=”1997961″]
Before we commit to that, let’s take a step back. At the end of Part II we refactored our scenarios into scenario outlines. We’ll write the scenario like that to save some refactoring later. We will also use the @wip tag so we can just concentrate on this test for now.
[gist id=”1997978″]
The example table holds the parameters for our scenarios. The parameters are the language, the original location name, the action to perform, and the label for the name field. The last parameter specifies the message displayed after the action completes.
Let’s add that to our /features/managing_locations.feature file. Run Cucumber and see what happens.
[gist id=”1997981″]
Not too bad. A couple of steps already pass. Cucumber is telling us what to do next. How would you “Update” the location “Name” to “New name”?
How about?
+ Go to a location’s page.
+ Click on the edit link.
+ Fill in the name field with our new location name.
+ Click the update button.
Sounds good, let’s write those steps.
Open up /features/stepdefinitions/locationssteps.rb and add those steps.
[gist id=”1997986″]
Does that make sense?
Since we created a location in an earlier step, we grab the first location. We also pass the locale. That will make the following route “/en/locations/1”. Thanks to Capybara the “Edit” link will get clicked. The form will get filled in. And the submit button will be clicked.
Think it’ll work? Let’s run Cucumber.
[gist id=”1997989″]
All right. Cucumber is guiding the next task: adding the edit link on the show page. Open up /app/views/locations/show.html.erb
[gist id=”1998101″]
Roll the dice.
[gist id=”1997996″]
We need to define the edit_location route. We can do that. Open up /config/routes.rb and, above the root route, add
[gist id=”1998000″]
That should do it. Cucumber, Let’er rip.
[gist id=”1998024″]
Huh? We need to add the edit action in the locations controller. Open the location controller file up and add that action
[gist id=”1998026″]
Second verse, same as the first. Rerun the test.
[gist id=”1998031″]
We need an edit page. Since our edit page and new page are the same we will combine them using partials. Make the form page and then include that partial in the new and edit pages. Extract the form from the new.html.erb file and paste it into the /app/views/locations/_form.html.erb
_form.html.erb
[gist id=”1998033″]
In the new.html.erb, call the form partial.
new.html.erb
[gist id=”1998035″]
The edit page looks very similar….
edit.html.erb
[gist id=”1998035″]
Let’s run the test and see what damage we’ve done.
[gist id=”1998037″]
We don’t see the update button.
According the the en.yml file the button will say Create. If we change that to Update then the test for Create will fail. The original form just had a <%= f.submit %> for the button and it knew when to say Create or Update. Let’s dig into the source code of rails and see how that works.
Check out the form helpers for the actionview around line 1064 it explains how that works. And, OMG, they tell us what to do when using i18n. Freakin’ awesome!
[gist id=”1998043″]
Now, update the en.yml file to reflect that.
[gist id=”1998047″]
Run the test.
WAIT! Look at what we did. We no longer have a .button_html in the en.yml file. Now, we’re saying that the helper for submit will say either Create for Post, otherwise it will say Update. That being said, we need to change the button in the form back to the default approach.
[gist id=”1998050″]
That feels cleaner.
[gist id=”1998054″]
_expected there to be content "location has changed" in "Internationalnnlocation 1nEditnn"_
HMMM…that doesn’t seem right. Why does it still say location 1? Let’s look at the test log file.
Open /log/test.log and look at the last few lines.
[gist id=”1998061″]
After the edit action, it’s routing to the show action. Routing issue! If you look at the last request Started PUT “/en/locations/1” for 127.0.0.1. It’s using the verb PUT to signify an update action. We have a route for /locations/:id and it goes to the show action. Since that route can use any verb, GET, PUT, or anything else, that route needs to respond to only a GET. Then we need to make a route for the update action that only responds to PUT.
Let’s open up the routes file.
[gist id=”1998065″]
Any bets? Will it pass? Roll the cucumber dice.
[gist id=”1998066″]
There we go. I was expecting this error. Let’s add the update action to the controller.
[gist id=”1998071″]
You know what to do next… rerun the test.
[gist id=”1998073″]
Break Time!
Implementar la prueba española
Let’s add the Spanish part of the scenario. Add the following valus to the end of the examples table.
[gist id=”1998075″]
Think it will all be green?
[gist id=”1998078″]
Alright, this is familiar. we need to change the es.yml file like we did the en.yml file. Open the spanish locale file.
[gist id=”1998080″]
Rerun the test. Go green!
[gist id=”1998084″]
Odd, that worked in the English version. If we fire up the rails server and go to the edit page of a location we see the name field says Name Html for both the English and Spanish locales. What happened? Let’s reflect a little… When we moved the form out of the new.html.erb file and placed it into the _form.html.erb file we didn’t reflect that change in our locale files. Let’s make that change in both locale files.
Before we test again, do you see why the English test passed? If you said it passed because “name” is in the label, you are correct. Take a bow.
Third verse, same as the first
[gist id=”1998086″]
Before we high five, remove the wip tag from the test and run cucumber to run all the tests.
[gist id=”1998097″]
…and curtain.
In this part we dug into the source code of rails. That wasn’t so scary. We looked at log files to help figure out what’s going on. Those are full of valuable information.
Now all we have to do is delete a location and we will have a simple internationalized web application.
Until then.