6.2. Adding Comments

Your visitors should be able to read articles and comment on them. The information that you need from each commenter is their name, their email address (which you won't display), and the body of their comment. Let's create a new resource for this.

Go ahead and run the following:

C:projectslog> ruby script/generate scaffold comment article:references
name:string email:string body:text

This is analogous to what you already did before for the article resource. The only part warranting explanation is article:references. It indicates that you need a foreign key that references the primary key of the articles table so that you can establish a one-to-many relationship between the articles table and the comments table. The foreign key in the comments table will be article_id. It will be an integer (just as the referenced id is).

references has an alias called belongs_to. Using article:belongs_to would have been acceptable as well.

The migration file looks like this:

class CreateComments < ActiveRecord::Migration
  def self.up
    create_table :comments do |t|
      t.references :article
      t.string :name
      t.string :email
      t.text :body

      t.timestamps
    end
  end

  def self.down
    drop_table :comments
  end
end

It is usually a very good idea to add indexes to foreign key columns. This can drastically improve performance. Before proceeding with the creation of the table, you should modify the migration file to add an index as shown here:

class CreateComments < ActiveRecord::Migration
  def self.up
    create_table :comments do |t|
      t.references :article
      t.string :name
      t.string :email
      t.text :body

      t.timestamps
    end

add_index :comments, :article_id
  end

  def self.down
    drop_table :comments
  end
end

Please note that add_index has an opposite method, called remove_index. For example, in the down method you could write remove_index :comments, :column => :article_id. This is not necessary, however, given that you already have drop_table :comments. When the table is dropped, the index you defined will be removed as well.

Now you need to evolve the current schema, which includes the articles table only, to a version that will include the new comments table as well. To do this, run rake db:migrate as you did in the previous chapter. If you look at the logdevelopment.log file, you'll see that the generated SQL query creates a comments table that includes an article_id column, the name, email, and body fields that you specified, plus the usual created_at and updated_at. You'll also see the following query for the index you defined:

CREATE INDEX "index_comments_on_article_id" ON "comments" ("article_id")

You can also see this in Ruby code if you take a look at the contents of the file dbschema.rb, which is generated after executing rake tasks that affect the schema (for example, db:migrate):

ActiveRecord::Schema.define(:version => 20080723022822) do

  create_table "articles", :force => true do |t|
    t.string   "title"
    t.text     "body"
    t.boolean  "published"
    t.datetime "published_at"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "comments", :force => true do |t|
    t.integer  "article_id"
    t.string   "name"
    t.string   "email"
    t.text     "body"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "comments", ["article_id"], :name => "index_comments_on_article_id"
end

This file can also be explicitly generated by running rake db:schema:dump and loaded into an empty database by running rake db:schema:load. schema.rb is essentially a translation, in Ruby code, of the database schema. This uses the ActiveRecord adapter for the specific database system to determine how to map SQL data types with Rails data types.

Because schema.rb is relied upon for generating the test database, if your database has database-specific column types that are not supported by the adapter or that use other db-specific features, which won't be "dumped" by the db:schema:dump task, it's far better to switch to an SQL-based creation of the test database by uncommenting the existing line in configenvironment.rb:

# Use SQL instead of Active Record's schema dumper when creating the test database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
config.active_record.schema_format = :sql

Fortunately, you don't need to do that in your case.

If you head over to http://localhost:3000/comments, you will probably be quite disappointed by the bare-bones look that is typical of the scaffold generator, as shown in Figure 6-2..

Figure 6.2. Figure 6-2

The reason for this is that the actions of the Comments controller are rendered using the comments.html.erb layout and not the articles.html.erb one that you've customized so far.

Things get even worse if you decide to accept the open invitation to click "New comment" as shown in Figure 6-3..

Figure 6.3. Figure 6-3

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.167.183