RailsSpace errata
These are all the known errata as of the first printing:
Chapter 2
- p. 19, Fig. 2.4. The Rails version (1.1.2) is out of date. It should read 1.2.3.
- p. 24.
gemservershould begem_server - p. 26 At the top of the page, both occurrences of
map.connect "should bemap.connect ''(one double quote to two single quotes) - p. 31. The two occurrences of
@contentforlayoutin the first full paragraph should be@content_for_layout - p. 31. In Listing 2.11, "Welcome to RailsSpace!" should be "RailsSpace"
- p. 33.
linktoshould belink_to
Chapter 3
- p. 48. The references to Section 4.2.3 should instead be to Section 4.2.2.
- p. 54. refl ecting should be reflecting
Chapter 4
- p. 79.
logs/development.logshould belog/development.log. - p. 84. "User foobar created!" should be "User created!"
- p. 86. Listing 4.17 is missing the nav div. Listing 4.17 on this site is correct.
- p. 89. In the variable interpolation sidebar, the irb session should look like this:
irb(main):001:0> title = "RailsSpace" => "RailsSpace" irb(main):002:0> "Welcome to #{title}!" => "Welcome to RailsSpace!" irb(main):003:0> 'Welcome to #{title}!' => "Welcome to \#{title}!"In other words, the first and second instances of
#titleshould have curly braces to give#{title}, while the third#titleshould also have a backslash at the front, giving\#{title}.
Chapter 5
- p. 102. etitle should be @title
- p. 105, 108. <legend>Register</legend> in the registration page HTML source views is inconsistent with the registration page from Chapter 4, which has instead <legend>Enter Your Details</legend>.
- p. 108. The screen name error in the HTML output is wrong. Instead of
Screen name is too short (minimum is 4 characters)it should beScreen name must contain only letters, numbers, and underscores - p. 112. At the bottom of the first paragraph, "users(:second)" should be "users(:another)".
- p. 119. All occurrences of the word "maximum" within the console output at the top should be "minimum".
Chapter 6
- In Rails 2.0.2 use
<pre><%= session.to_yaml %></pre>instead of<%= debug(session) %>. - Instant Rails Users - Testing flash[:notice]
Instant Rails is a bit smarter than regular Rails when it comes to the flash[:notice] assignment and de-assignment. In Instant Rails, as soon as the flash[:notice] is used, it gets nullified. So, the flash message appears, but then this test:
assert_equal "Invalid screen name/password combination", flash[:notice]fails because the flash is already nil. So, you have to instead check the HTML that was that delivered:
assert_tag :div, :content => "Invalid screen name/password combination", :attributes => { :id => "notice" } - p. 133. Rails 2.0 users might get errors like
ActionController::InvalidAuthenticityToken in User#register Showing user/register.html.erb where line #2 raised: No :secret given to the #protect_from_forgery call. Set that or use a session store capable of generating its own keys (Cookie Session Store).
This is a known problem in Rails 2. To fix it, comment out the line with the :secret key in app/controllers/application.rb. - pp. 136-139. The screenshots have the Register link right-aligned, but really they should be at the left with the other links.
- p. 153. In the box "A rough edge", two instances of unless should be if:
should beunless session[:user_id] == nil
andif session[:user_id] == nil
should beunless session[:user_id].nil?if session[:user_id].nil? - p.175. There is an unnumbered code listing with code that belongs in
app/controllers/user_controller.rb. It is numbered as listing 6.47.5 above. - p. 179. Depending on your system, you may have "17 tests, 80 assertions".
Chapter 7
- p.201. Listing 7.17 has a stray line return:
should beuser.authorization_token = Digest::SHA1.hexdigest( "#{user.screen_name}: #{user.password}")user.authorization_token = Digest::SHA1.hexdigest( "#{user.screen_name}:#{user.password}") - p. 221. Listing 7.40. There's an extra space in
user.forget! (cookies); i.e., it should just beuser.forget!(cookies).
Chapter 8
- p. 244. Listing 8.21
def assert_length(boundary, object, attribute, length options = {})is missing a comma. It should bedef assert_length(boundary, object, attribute, length, options = {}) - p. 244, footnote. Cross reference should be "7.1.3" instead of "7.13".
Chapter 9
- p. 268, last line.
<%= text_field_for form, "Last name" %>should be<%= text_field_for form, "last_name" %> - p. 276. Listing 9.20 is a snippet of a file, not the entire file, and
Spec.new should take an argument setting its user id:
To get this to work, you need to add the users fixture to spec_test.rb:# Test a saving a blank spec. def test_blank blank = Spec.new(:user_id => @valid_spec.user.id) assert blank.save, blank.errors.full_messages.join("\n") end
The code listed here on the web site is correct.class SpecTest < Test::Unit::TestCase fixtures :specs, :users . . . - p. 283. Listing 9.28 should should really be around the code at the bottom of the page, i.e., first we recall the old code, which should not be called listing 9.28, and then we replace it with new code that is changed and should be listing 9.28. The code listing on the web site is correct.
- p. 284. The user controller listing at the bottom of the page should have been numbered, and the code is included here as Listing 9.29.5.
- p. 289. Listing 9.34 should be titled db/migrate/006_create_faqs.rb.
- p. 296. We refer to Figure 9.9 on the page, but the reader should be aware that Figure 9.9 won't display until the creation of the _sidebar_box.rhtml file in Listing 9.47 on pages 297-298.
- p. 301. Listing 9.52 should be titled app/views/profile/show.rhtml
Chapter 10
- p. 312. Listing 10.4 is titled app/views/controllers/community_controller.rb but but should be app/controllers/community_controller.rb
- p. 317. A reference to app/view/profile/show.rhtml should be app/views/profile/show.rhtml
- p. 318. There's a logic error in the calculation of the user's age in the spec model. Listing 10.11, which appears as
should instead be# Return the age using the birthdate. def age return if birthdate.nil? today = Date.today if today.month >= birthdate.month and today.day >= birthdate.day # Birthday has happened already this year. today.year - birthdate.year else today.year - birthdate.year - 1 end end# Return the age using the birthdate. def age return if birthdate.nil? today = Date.today if (today.month > birthdate.month) or (today.month == birthdate.month and today.day >= birthdate.day) # Birthday has happened already this year. today.year - birthdate.year else today.year - birthdate.year - 1 end end
Chapter 11
- p. 331. The command line to install the Ferret plugin spans two lines and it's not clear that it's not supposed to. The full line is:
ruby script/plugin install svn://projects.jkraemer.net/acts_as_ferret/tags/stable/acts_as_ferret - p. 334. Listing 11.8 is missing an end after
@users = @users.sort_by { |user| user.spec.last_name }:
def search @title = "Search RailsSpace" if params[:q] query = params[:q] # First find the user hits... @users = User.find_by_contents(query, :limit => :all) # ...then the subhits. specs = Spec.find_by_contents(query, :limit => :all) faqs = Faq.find_by_contents(query, :limit => :all) # Now combine into one list of distinct users sorted by last name. hits = specs + faqs @users.concat(hits.collect { |hit| hit.user }).uniq! # Sort by last name (requires a spec for each user). @users.each { |user| user.spec ||= Spec.new } @users = @users.sort_by { |user| user.spec.last_name } end end - p. 339. Section 11.1.5 - Depending on which version of Ferret you have installed, you may not get an error at all when searching for "--". They fixed this bug but it is still a good idea to handle exceptions.
- p. 342. Listing 11.16 should be titled test/functional/community_controller_test.rb
- Some listings are titled app/views/controllers/community_controller.rb but should be app/controllers/community_controller.rb
- p. 344. Listing 11.17
- p. 345. Listing 11.20
- p. 361. Listing 11.30
- p. 361. Listing 11.31
- p. 343. The test code given in Listing 11.16 requires the creation of the
YAML file in
test/fixtures/geo_data.ymlwith some contents like:Caltech: id: 1 zip_code: 91125 latitude: 33.7866 longitude: -118.299 city: PASADENA state: CA county: LOS ANGELES type: - p. 349. All occurrences of "find_by_sql" should be "find_by_asl".
Chapter 12
- p. 370. Listing 12.6 should be titled app/controllers/profile_controller.rb
-
p. 376. In the footnote,
ln -s /usr/local/bin/convert/usr/bin
is missing a space; it should beln -s /usr/local/bin/convert /usr/bin
- p. 386. Listing 12.21 should be titled test/test_helper.rb
Chapter 13
- p.403. Figure 13.3 The URL is wrong. At some point we changed the user names in the default data set from firstname_lastname to firstinitial_lastname, so Frank Capra's screen name is 'f_capra' and the URL should be http://localhost:3000/email/correspond/f_capra.
Chapter 14
- p.419. Listing 14.5 should be test/unit/friendship_test.rb instead of test/units/friendship_test.rb.
- p. 430. Add the following validition to the User model to avoid overwriting the default avatar images:
def validate # Protect against overwriting default thumbnail... if %w(default_thumbnail default).include?(screen_name) errors.add(:screen_name, "cannot be that, nice try though") end end
Chapter 15
- p. 446. Listing 15.3 should be titled db/migrate/009_create_blogs.rb
- p. 449. The code output should have "create db/migrate/010_create_posts.rb"
- p. 448. For Rails 2.0, replace scaffold_resource with scaffold
- p. 449. Listing 15.7 should be titled db/migrate/010_create_posts.rb
- p. 454. Listing 15.9 should be titled app/models/post.rb
- p. 457. There is a missing listing number for the posts controller code on this page, it is included on the web site as Listing 15.11.5 above. Also, the second line should read
helper :profile, :avatar. - p. 458. There's a security flaw that allows users to edit others' posts as long as the URL contains their blog id; i.e., if yours is blog 2, you can edit post 17 even if it isn't yours by going to /blogs/2/posts/17;edit. The following code fixes this:
class PostsController < ApplicationController helper :profile, :avatar before_filter :protect, :protect_blog before_filter :protect_post, :only => [:show, :edit, :update, :destroy] . . . private # Ensure that user is blog owner, and create @blog. def protect_blog @blog = Blog.find(params[:blog_id]) user = User.find(session[:user_id]) unless @blog.user == user flash[:notice] = "That isn't your blog!" redirect_to hub_url return false end end def protect_post post = Post.find(params[:id]) unless post.blog == @blog flash[:notice] = "That isn't your blog post!" redirect_to hub_url return false end end end - p. 477. To test the code in the erratum on p. 458, change the Posts fixture in test/fixtures/posts.yml to
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html one: id: 1 blog_id: 1 title: MyString body: MyText created_at: 2007-01-18 08:43:03 updated_at: 2007-01-18 08:43:03 two: id: 2 blog_id: 2 title: MyString2 body: MyText created_at: 2007-01-18 08:43:03 updated_at: 2007-01-18 08:43:03
and then add this to the Posts controller test:def test_post_blog_mismatch wrong_post = posts(:two) # Post exists, but belongs to wrong blog. get :edit, :id => wrong_post, :blog_id => @post.blog assert_response :redirect assert_redirected_to hub_url assert_equal "That isn't your blog post!", flash[:notice] end
Chapter 16
- p. 480. The code output should have "db/migrate/011_create_comments.rb"
- p. 480. Listing 16.1 should be titled db/migrate/011_create_comments.rb
- p. 483. Listing 16.5 There should be a vertical ellipsis ... before
private - p. 486. The reference in the second paragraph to Section 6.2.2 should be 6.2.3.
- p. 503. In Listing 16.28, change
tofixtures :comments, :posts, :blogs, :users, :specsfixtures :comments, :posts, :blogs, :users, :specs, :geo_data
Back cover
- "RailSpace social network" should be "RailsSpace social network"