Maverick
Maverick

Reputation: 2760

ruby on rails associations newbie

This might be considered as a re-post of rails 3 associations error. But its something which I am not able to understand . But ok ... heres the deal.. I have asked a question in here which was related to a table schema. The post is what is bad in this table schema structure and the query was :

`CREATE TABLE "pages" (
   "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
   "title" varchar(255),
   "body" varchar(255),
   "author" varchar(255), 
   "email" varchar(255), 
   "reference" varchar(255),
   "created_at" datetime,
   "updated_at" datetime);`

I was suggested that I should create separate tables for author, and that is what I tried and messed up. Can anyone please tell me how exactly should the associations work with my scenario? I really need to understand the ROR associations well.

edit-1

Here is my pages migration code:

class CreatePages < ActiveRecord::Migration
  def self.up
    create_table :pages do |t|
      t.string :title, :unique => true, :limit => 50
      t.string :body, :limit =>255
      t.string :email, :unique => true, :limit => 50
      t.string :reference, :limit => 40
      t.timestamps
    end
    
  end

  def self.down
    drop_table :pages
  end
end

and here is my author migrations:

class CreateAuthors < ActiveRecord::Migration
  def change
    create_table :authors do |t|
      t.string :author, :unique => true, :null => false, :limit => 50
      t.timestamps
    end
  end
end

Upvotes: 0

Views: 715

Answers (2)

Alex D
Alex D

Reputation: 30445

Creating a separate table for authors is probably a good idea (although if this working well for you already, and you don't have any performance problems, you could just leave it as is).

@Marc Talbot already gave a good answer about how to set the associations up in your Rails models. Of course, you will also need to migrate your database. This is what to do:

  1. Make a table called "authors". Besides the primary key "id", it should have a field called "name", as well as "email". You can move any other fields which will logically always be the same for the same author from "pages" to "authors".
  2. Add an integer field "author_id" to "pages".
  3. Run over the existing entries in "pages". For each page, check whether the author is already in "authors". If not, add the author to "authors", and fill in "name", "email", and the other fields in "authors". Set "author_id" to refer to the correct ID from the authors table.
  4. Drop "author", "email", and the other moved fields from "pages".

Upvotes: 1

Marc Talbot
Marc Talbot

Reputation: 2059

If we think this through logically, an author might have many pages, and pages belong to an author. If that's the case, we can express this through rails relationships.

class Author < ActiveRecord::Base
  has_many :pages

class Page < ActiveRecord::Base
  belongs_to :author

In order to support this, you'll need to create a migration to ensure that there is an author_id column in your pages table. Rails takes care of the rest. You'll get all the relationship semantics like:

my_page.author.email
my_page.author.name

(assuming that your Author class has such attributes)

Note that you don't necessarily have to have an Author class if your Users are your authors. If every Author is a User (and you use your User class for authentication and account maintenance), you can still refer to the User as an Author of a class

class Page < ActiveRecord::Base
  belongs_to :author, :class_name => "User"

which lets you keep the nice author semantics by does them against your User class.

Final note, if you want to automatically delete any pages associated with an author when you delete an author object, you can add dependence to the Author class

class Author < ActiveRecord::Base
  has_many :pages, :dependent => :destroy

Upvotes: 1

Related Questions