Datasheet
Chapter 1: Building Resources
33
To make this work, the Recipe class is augmented with a getter and setter method for the attribute
ingredient_string — this is the slightly unusual case where you want a getter and setter to do
something genuinely different. The setter takes the string and converts it to ingredient objects, and the
getter returns the recreated string:
def ingredient_string=(str)
ingredient_strings = str.split(“\n”)
order_of = 1
ingredient_strings.each do |istr|
next if istr.blank?
ingredient = Ingredient.parse(istr, self, order_of)
self.ingredients < < ingredient
order_of += 1
end
save
end
def ingredient_string
ingredients.collect { |i| i.display_string}.join(“\n”)
end
At this point, the earlier test of the entire form should also pass.
The setter splits the strings on newline characters, and then parses each line, skipping blanks and
managing the order count. When all the ingredients have been added, the recipe is saved to the database
with the new ingredients. The getter gathers the display strings of all the ingredients into a single string.
Finishing up the testing of the basic controller features in
test/functional/recipe_controller_
test.rb
, the edit and update tests are augmented as follows:
def test_should_get_edit
get :edit, :id = > 1
assert_response :success
assert_select(“form[action=?]”, recipe_path(1)) do
assert_select “input[name *= title]”
assert_select “input[name *= servings]”
assert_select “textarea[name *= ingredient_string]”
assert_select “textarea[name *= description]”
assert_select “textarea[name *= directions]”
end
end
def test_should_update_recipe
put :update, :id = > 1,
:recipe = > {:title = > “Grandma’s Chicken Soup”}
assert_redirected_to recipe_path(assigns(:recipe))
actual = Recipe.find(1)
assert_equal(“Grandma’s Chicken Soup”, actual.title)
assert_equal(“1”, actual.servings)
end
c01.indd 33c01.indd 33 1/30/08 4:02:30 PM1/30/08 4:02:30 PM