Ruby on Rails: Up and Running by Bruce A. Tate, Curt Hibbs The unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification This page was updated April 1, 2008. UNCONFIRMED errors and comments from readers: [NA] NA; Having built the application, and then downloaded the code examples, I find that if I use either my application or the code samples, the application seems to work okay; however, I get a RecordNotFound exception on the console EVERY TIME I reorder the slides after I have dragged- remove a slide from a slide show. What gives? Is there some way to update 'sortable_thumbs' so it doesn't include the id that was removed (00) ORA website; The sample code needs more careful administration. src-start-chapter3.zip unzips into photos src-start-chapter4.zip unzips into photos src-start-chapter5.zip unzips into src-start-chapter-5-zip src-start-chapter6.zip unzips into src-start-chapter-7-zip src-start-chapter7.zip unzips into src-start-shcapter-8-zip [7] 2nd paragraph, first bullet item under 1.4 The Web Server; Text says: "The server started on port 3000. You can change the port by editing the script/server script. See the sidebar "Configuring the Server" for more configuration options." Then the sidebar goes on to talk about editing the startup script. This is not something you usually want to do. Instead most of those default options can be overridden with command line switches. For example, to start the server with a different port, just send in the -p switch with the port you want to use: ruby script/server -p 3001 You can see the command line options available to the server with: ruby script/server -h => Booting WEBrick... Usage: ruby server [options] -p, --port=port Runs Rails on the specified port. Default: 3000 -b, --binding=ip Binds Rails to the specified ip. Default: 0.0.0.0 -e, --environment=name Specifies the environment to run this serve r under (test/development/production). Default: development -m, --mime-types=filename Specifies an Apache style mime.types config uration file to be used for mime types Default: none -d, --daemon Make Rails run as a Daemon (only works if f ork is available -- meaning on *nix). -c, --charset=charset Set default charset for output. Default: UTF-8 -h, --help Show this help message. (7) middle of the page; In the section "Configuring the Server", the text shows how to edit the default options contained in script/server. I only see the following lines in script/server: #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/boot' require 'commands/server' Is this a difference in rails versions? Or do to a setup using lighttpd? [11] In sidebar last paragraph; The URL http://rubyonrails.org/show/Generators will give you an error from that site. I found the login generator at rubyforge.org (15) last paragraph; The descriptions of the code examples starting on this page and into page 16 read as if they are explaining the following code, but actually explain the code already displayed. Confusing to the reader. [16] 2nd text paragraph; "Now, display the value of the instance variable @age, which was ...." This is clearly incorrect if it is referring to the subsequent code. It should use i (which is the iteration variable). @age is used previously. (16) Paragraphs 2, 3 ,4; These sentences should be before the examples: "Now, display the value of the instance variable...." should be above "

Simple expressions

" "Iterate with a scriplet..." should be above "

Interation using scripts

" "Finally, use both techniques to display the ...." should be above "

A simple table

" {21} Define the Model. last paragraph; QUOTE: "we'll use an arrow to mean 'belong to', so the arrow will point from the one to the many." This seems to contradict the third bullet point earlier, "A slideshow has many slides" when looking at Fig.2-1 (pg.22). Also, should the arrows in the Fig.2-1 be in the same direction, represent Photos 'belonging to' many Slides and Slides 'belonging to' many Slideshows. {22} Figure 2-1; Slides and photos have a one-to-one relationship. Arrow connecting them should have no heads. [22] Figure 2-1; On page 21, the text says the arrows will point from the one to the many. On page 22, the arrows from photos to slides and slideshows to slides are backwards. On page 21, IMHO you have stated the preferred way of expressing this relationship. I have to admit that there are those who like the arrows the other way. Just be consistent. In my opinion, somewhere it should be stated that this particular relationship is an example of the classic "many to many". This is very confusing when one goes on to learn about "belongs_to" in Chapter 3. {22-23} First paragraph in Schema Migrations and following text; In the text you say: "We assume that you're working from the MySQL command prompt, ... However on page 23 you say: "For now, just generate the model object by typing: ruby script/generate model Photo " which must be from the shell. (24) db/migrate example; In more recent versions, all the strings in this example become symbols, e.g.: create_table "photos" do |photo| becomes create_table :photos do |photo| (24) 3rd paragraph, code snippet: Class CreatePhotos; The text uses string notation ("photos"), whereas the original code created by "script/generate model Photo" uses symbol notation (:photos). [24] code show and following para, 3rd line; The statement talking about the up methad states "... two columns, filename and id,..." But the previous code only shows a single column, photo.column [24] middle, also elsewhere -- search the PDF Rough Cuts version; Several errors, and one serious error that breaks the tutorials with the current version of Rails. The book mentions a class named "Person" several times when I believe it is meaning to refer to a class called Photo: "Let\u2019s review what happens when Ruby loads the Photo class. From the class name Person, Active Record infers that the database table name is photos" (Page 24 of my PDF) Search the PDF Rough Cuts version to find all the mentions of "Person". Following the tutorial in the book doesn't work with the latest version of Rails. The main problem I've encountered so far is that you don't need to do ./script/generate migration add_photos (output below). Rails automatically creates a migration when you create the model photo. $ ./script/generate migration add_photos exists db/migrate create db/migrate/002_add_photos.rb This shows migration being generated when I make the model: $ ./script/generate model photo exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/photo.rb create test/unit/photo_test.rb create test/fixtures/photos.yml create db/migrate create db/migrate/001_create_photos.rb <-note that this is created here If you do it the way that is mentioned in the book, there are errors and it doesn't work. The code inside of db/migrate/001_create_photos.rb is also somewhat different than what is described in the book. [26] 3rd of 4 code blocks; The console commands photo.filename = 'cat.jpg' and the equivalent dog.filename = 'dog.jpg' return: NoMethodError: undefined method `filename='... (see below). Why? Perhaps the 2nd code block on p.24 (class CreatePhotos...) is incorrect? Whatever the cause, it is not possible to add records to the db, and thus much of the remainder of the chapter cannot be completed. (Of course, the table never acquires a column called filename, when queried via SQL.) C:\ruby\photos>ruby script/console Loading development environment. >> photo = Photo.new => # >> photo.filename = 'cat.jpg' NoMethodError: undefined method `filename=' for # from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_recor d/base.rb:1789:in `method_missing' from (irb):2 >> (32) Figure 2-4 title; Instead of "Composed of maps many objects onto one table" consider using "Composed_of" and/or using code font instead of "Composed of", as in Table 2-3 on p.33. (32) Figure 2-4; The "Address" table is missing "state" and "zip." (An alternative is to add a third row that says "...", but adding two rows is probably no harder than adding one.) [34] 1st paragraph; The following ... cat.update ... gives an error. It should be ... cat.save ... The update method takes an id and attributes. (35) Last paragraph on page; Paragraph states that inheriance and composition relationships will be covered in chapter 3; these relationships were already detailed in chapter 2 (pages 30-33). Chapter 3 does not mention composition and inheritance at all. (36) description of "named parameters"; an optional number of named parameters should be an arbitrary number of named parameters {36} last line of page; The text says: has_many :photos :order => position But a more logical example in this context of the book would be: has_many :slides :order => position (i.e. slides instead of photos) {37} 1st sentence after example started on previous page; Edit the new migration in db/migrate/create_slide.rb, like this: should be Edit the new migration in db/migrate/003_create_slides.rb, like this: (38) first sentence following code example at the top; The sentence: "Edit the new migration in db/migrate/create_slide.rb..." should be: "Edit the new migration in db/migrate/003_create_slides.rb..." (38) The last command on the page....; Same as error on page 24. The code "rake migrate" will produce a deprecation notice when executed. It should be "rake db:migrate". {39} sql statement; Not a technical mistake, but a note to the editors of the book. It's a pain when you know sql, and you have a type a huge sql query into your code, just to move forward with the examples in the book. There was a good suggestion to put the .sql file the book refers to in the downloadable code. This would save your customers some time. {39} 4th paragraph; You should update and save the models with has_many relations shown on page 40 before doing what this sentence says: Start the MySQL prompt, type use photos_development, and execute the script by typing source db/slideshow_data.sql at the MySQL prompt. [40] Table 3-1; The distinction stated between build_ and create_ is incorrect. Both methods accept a hash map of attributes; create_ saves the created object immediately, build_ does not. The fact that slide.photo.id (not "photo.slide") is nil between invoking slide.build_photo and invoking slide.save is a side-effect of this. References to ""the root object" are confusing and incorrect. A required right parenthesis has been omitted from the build_ and create_ examples. The second line of the description of the attribute is not a code example; it should not be indented and the words 'on', 'allows' and 'and' should be set in the same font as the text of the first line. (40) Table 3-1; I think that the "Description" for the "Added Feature" build_ is wrong; should it be this instead? slide.build_photo( { :filename => "cat.jpg" } ) And it's not clear to me what this means: "In this example, photo.slide is initialized to nil." (40) Table 3-1; The last example of repeats "slide.photo"; it's not clear what was meant here. IMHO the safest thing here to do is to delete "and slide.photo" from the example unless you want to also illustrate a similar attribute for "belongs_to :slideshow" on Slide. {40} Table 3-1; I think the line "In this example, photo.slide is initialized to nil" should read "In this example, slide.photo is initialized to nil" {40} 3rd paragraph (following the slideshow_data.sql script); This may be my mistake... I tried running the script by following the instructions: 1. Download the SQL script and save it in the db folder as file slideshow_data.sql... 2. cd to .../photos 3. Start MySQL 4. type use photos_development 5. [type] db/slideshow_data.sql Result: ERROR 1064 (42000): You have an error in your SQL syntax; If I run this as: 1. cd to .../photos 2. Type: C:\work2\photos>mysql -uroot -pxxx photos_development "cat.jpg" should be slide.build_photo( { :filename => "cat.jpg" } ) 2) .create: slide.build_photo(:filename => "cat.jpg" should be slide.create_photo( { :filename => "cat.jpg" } ) Also, I'm not understanding the "In this example, photo.slide is initialized to ..." sentences. (45) Last Paragraph; "categories is not a model table, so it needs no id." should be: "categories_photos is not a model table, so it needs no id." (46) example at bottom of page; Example should read: >> category = Category.find_by_name "Animals" ... >> category.photos.each {|photo| puts photo.filename} camel.jpg cat_and_candles.jpg polar_bear.jpg >> photo = Photo.new ... >> photo.filename = "cat.jpg" => "cat.jpg" {46} Last two lines of example at foot of page; These lines are not wanted here. They seem to have been duplicated from the example at the top of page 47. They are also wrong (and this applies at the top of page 47, too): no variable or method called 'photo' exists at this point. This code would work: photo = Photo.new (:filename => "cat.jpg") {46} The query photos_data.sql doesn't work...; Rather than adding the insert transactions shown on page 46,to the photos_data.sql script, I used the slideshow_data.sql script... It doesn't work...somehow, the table categories was populated, prior to running the script, with: mysql> select * from categories; +----+------+-----------+ | id | name | parent_id | +----+------+-----------+ | 1 | All | NULL | +----+------+-----------+ Deleting this row and running the script again using C:\...>mysql -uroot -pPswd photos_development >photo.filename = "cat.jpg" -- see page 26] photo = Photo.new It will then work -- it solves the followin Unconfirmed error reports and comments from readers: [47] 1st code sample; The command you are told to enter in doesn't work. Here is the output: >> photo.filename = "cat.jpg" NameError: undefined local variable or method `photo' for # from (irb):1 [47] 1st code sample; The command you are told to enter in doesn't work. Here is the output: >> photo.filename = "cat.jpg" NameError: undefined local variable or method `photo' for # from (irb):1 [49] 1st paragraph; In order to prevent an error, your should restart to console before doing the example queries. [49] 1st paragraph; As of Rails 2.0, the acts_as_X features have been moved out of the Ruby core and into individual plugins. So before you can use acts_as_list, you must install it: ruby script/plugin install acts_as_list {49} 2nd example; The output shown assumes that the first two slides (of the dataset constructed so far in the examples) have already been moved to the end of the list. (49) 1st paragraph after code; "By convention, positions start at..." What convention? Certainly not the C, C++, Java, Perl, etc. convention. (Pascal starts at one, with [0] being the number of elements in the array.) I'd omit "By convention" but it's not my book. [51] 3rd paragraph; As of Rails 2.0, the acts_as_X features have been moved out of the Ruby core and into individual plugins. So before you can use acts_as_tree, you must install it: ruby script/plugin install acts_as_tree {54} 4th line in example; render_text('Welcome to Photo Share's Title Page') should be render :text => 'Welcome to Photo Share's Title Page' [55] footnote; The code on the ORA website for this book ("If you haven't been coding along but witsh to start ...") doesn't work. So far: (a) Permissions are wrong, so code won't execute. (b) MS-DOS-specific paths are hard-wired into it. Please either have someone try code on a Linux box or a Mac before you distribute it, or mark it as "Microsoft only," so we know it'll be a bunch of work to get it to run. (56) Table 4-1, for the purpose of the "new" method; create a new controller object should be create a new target object {58} code example on the end of the page; In the downloadable example for Chapter 5 (compare p. 67), the SQL-file "create_tables_with_data.sql" uses the extension *_t.jpg for the thumbnails. The code for the migration-file, creating the column 'thumbnail' in the MySQl-table "photos," on page 58 uses *_m.jpg as the thumbnail-file-extension instead. I suppose this line on page 58: photo.update_attribute :thumbnail, photo.filename.gsub('.', '_m') has to be changed to: photo.update_attribute :thumbnail, photo.filename.gsub('.', '_t) to be consistent with the example file for chapter 5. {67} 2nd Paragraph; Don't bother trying to copy the images from the downloadable project to the project you created in the tutorials in Chapters 1 through 4. The image names (including thumbnails) are completely different from the names given in the sample data in earlier chapters. The best way to proceed is to set aside your work from Chapters 1 through 4 and proceed with the download. {69} 'delete me' link; If you are using the Rails generated code, you must add: :post => true to the 'delete me' tag; otherwise, the delete won't execute. Corrected code below: <%= link_to 'delete me', { :action => 'destroy', :id => photo }, :confirm => 'Are you sure?', :post => true %> Rails generates a verify that all destroy actions are generated from posts only. [71] just below middle of page; <%= link_to('delete me',{:action => 'destroy', :id => photo}, :confirm => 'Are you sure?') %> should be <%= link_to('delete me',{:action => 'destroy', :id => photo}, :confirm => 'Are you sure?', :post => true) %> ":post => true" is necessary as the default would be 'get' instead of 'post' and for a delete link this is not allowed, even forbidden by the Rails framework {74} last sentence; Last line should (We no longer ...) precede the second-to-last (Now you can click ...), as the other layout files must first be removed as they would otherwise override standard.rhtml. {77} Right under figure 5-5; It says to use #thumbnail and use id as the identifier for the image. It should be class instead of id since the element repeats several times on the page. {81} middle of page; Editing category hierarchy may create endless loop. The drop down selection allows any category to be selected as its own parent category, which causes an endless loop. For example when editing the category "All:People:Family", a user can choose from the drop down menu "All:People:Family" as its parent category. By doing this, the method "ancestors_name" and "long_name" loops back on itself. To fix this problem, the drop down selection should exclude the category (All:People:Family) that is being edited. As it is now, ALL categories are listed... (controllers/categories_controller.rb) def edit @category = Category.find(params[:id]) @all_categories = Category.find(:all, :order=>"name") end (categories/_form.rhtml <%= collection_select(:category, :parent_id, @all_categories, :id, :long_name) %> (models/category.rb ancestors_name and long_name loops on itself) class Category < ActiveRecord::Base has_and_belongs_to_many :photos acts_as_tree def ancestors_name if parent parent.ancestors_name + parent.name + ':' else "" end end def long_name ancestors_name + name end end [84] In 5.7 Styling the Slideshows In the CSS file you label things slideshow-*, but up above you id the divs with 9780596529444-*. Thus they do not match up. Luckly I know enough about CSS to know what was happening, but most people won't. ALSO in the downloadable code for Chapters 6 and 7 they is a screwup. The initial diretory in each zip is labeled one chapter too high. SO Chapter 6 unzips to hold a directory labeled start-chapter-7-zip and Chapter 7 unzips to hold a directory labeled start-chapter-8. {84} Bottom code example on the page; Figure 5-10 shows "New Slideshow" link which is not shown in the source. {84} Bottom code example on the page; HTML source shows the use if ids instead of classes for repeating elements. [84] bottom of the page; The book instructs: "Edit the view template (app/views/slideshows/list.rhtml) to look like this:" But if you do that, you lose the link_to for the new slideshow. This code example you really have to work over, because the new code is meant to replace the guts but go in a different order. In the scaffolded code, the 'new' link is at the bottom of the guts, whereas in the finished picture example, the 'new' link is on top. So instead of just making the template "look like this" you have to thoughtfully discard everything above the 'new' link in the scaffolded code, then add the new code on pages 84 and 86. But this isn't clear until after you've finished all the work in the chapter and are comparing your screen to the provided screen shot. It ends up being just one line. But to someone new to Ruby on Rails, it's very distracting. [87] 1st paragraph under Creating the Stylesheet; The text says: Remember that we set up our view template with id= attributes: for example, "slideshow-summary" and "slideshow-thumbnails"... This is incorrect. We set up our view template with id attributes such as "9780596529444-summaries" and "9780596529444-thumbnails". And as a result, the div ids given in the code we're supposed to enter into app/controllers/slideshows_controller.rb don't match the div ids in the CSS we're supposed to enter into public/stylesheets/slideshows.css. Thus, the stylesheet stuff is never applied, and the display never looks like figure 5.12. [87] def thumbnail_tag code block; Since the CSS selector for slideshow-summary sets a width of 25em, this definition for the thumbnail_tag needs to follow the size descriptor used in the list function, otherwise the float positioning is unpredictable based on window width. def thumbnail_tag(slide) image_tag "photos/#{slide.photo.thumbnail}" if slide end Should be: def thumbnail_tag(slide) image_tag ("photos/#{slide.photo.thumbnail}", :size => '75x56') if slide end [92] Entire Section; After following your instructions, rechecking my code several times, and finally copying the files from your "start-chapter-7" archive over my files, I consistently get the following error message: NoMethodError in Slideshows#show Showing app/views/slideshows/_show_slide.rhtml where line #1 raised: You have a nil object when you didn't expect it! The error occurred while evaluating nil.photo Extracted source (around line #1): 1: <%= image_tag "photos/#{@slide.photo.filename}" %> 2:

<%= @slide.photo.filename %>

Trace of template inclusion: /app/views/slideshows/show.rhtml RAILS_ROOT: ./script/../config/.. By the way, I also updated my database using your .sql file included in the "start-chapter-7" file. I tried this on IE 7 and Firefox 2.0, both running on a Windows XP machine. I'm using Ruby 1.8.6 and Rails 1.2.5. {94} controller segment; There is a problem with the way that you implement the controller for the slideshows. When the slideshow has shown all of the available pictures, the session[:slide_index] is advanced by 1 and therefore @slide is referencing to nil but for some reason. There is a check to see if @slide is nil but I get the following once the whole show has gone through: Photos Categories Slideshows Interesting pictures NoMethodError in SlideshowsController#show_slide You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occured while evaluating nil.- [96] 4th paragraph; beginning of for loop missing between ############ begin for loop <% for slide in @slideshow.slides %> ###############
  • <%= thumbnail_tag slide %>

  • <% end %> <%= sortable_element('sortable_thumbs', :url => {:action => 'update_slide_order'}) %> [96] 4th Paragraph (photos/app/views/slideshows/_show_slides_draggable.rhtml example); single quotes for the HTML id attribute render the list un-draggable in Firefox 2.0.x for OS X and PC as well as Safari. By changing the single quotes to double quotes the following code works just fine:
      <% for slide in @slideshow.slides %>
    1. <%= thumbnail_tag slide %>
    2. <% end %>
    <%= sortable_element('sortable_thumbs', :url => {:action => 'update_slide_order'}) %> This problem also applies to the example code for photos/app/views/slideshows/edit.rhtml found on pages 95, 96 and again on page 100. (96) 3rd code listing; The code listing refers to two ids, which are used to reference the objects that will be displayed in the slideshow. However these ids should also have corresponding entries in a CSS style sheet. It is evident in the screenshot on page 98 that these are used in the application, so there should be a listing here. {98} code example; To make the CSS code shown on page 106 work, this example needs to set the 'class' attribute, as in the corresponding dowloadable example: module SlideshowsHelper def thumbnail_tag(slide) image_tag("photos/#{slide.photo.thumbnail}", :style => "vertical-align:middle", :class => "thumbnail") if slide end end In addition, the :style attribute should be :style => 'vertical-align:middle;margin-bottom:1em' if you want the thumbnail spacing shown in figures 6-2 and 6-3 (because the css file has not yet been edited for img.thumbnail at that point in the book). [100] not sure where it should go; The method remove_slide is not present in the book. I created one ( please forgive me I'm just starting out with ruby/rails) that seems to work... def remove_slide slideshow_id = session[:slideshow].id @slideshow = Slideshow.find(slideshow_id) slide_id = params[:id].split("_")[1].to_i Slide.find(slide_id).destroy @photos = unused_photos(@slideshow) render_partial 'photo_picker' end (100) 3rd paragraph; Not sure about the page number, but you said in the book that you could download the appendix/ quick reference on this website, and there doesn't appear to be a link for that. {101} 4th paragraph (excluding code listings); "Finally, notice two Ajax related helpers: drop_receiving_element and observe_field." Only the first of these two helpers is actually displayed in the preceding code - that is, observe_field is not described in the listing (it is shown on page 107). (108) top; Figure 6-6 should not include a filter on category since it has not been yet created to the time it is cited in text. Actually Figure 6-6 is almost identical to Figure 6-7. [109] Middle; After implementing the changes the application would get stuck in a loop if either the Category or the Slideshow pages were referenced(and they were working before the filtering iteration). Looking a the server log, there seemed to be a problem with the find category function(perhaps changes while fooling with the drag drop slideshows caused a problem?) I reloaded the sql data file and then the program functioned correctly. {122} bottom 3rd of page; You mention to edit the photos_controller_test.rb and to add lines to the class definition for CategoriesControllerTest, and there isn't one. Do you mean to put these two lines in the categories_controller_test.rb? If so, you only need to add one of the lines.