has_many

Creating the database

if the tables don’t exist yet

% script/generate model Flock
% script/generate model Bird

codetitle. db/migrate/001_create_grants.rb

class CreateBird < ActiveRecord::Migration
  def self.up
    create_table :birds do |t|
      t.column :flock_id, :integer
    end
    add_index 'birds', ['flock_id'], :name => 'index_flock_id'
  end
  def self.down
    drop_table :grants
  end
end

if the tables already exist

% script/generate migration AddFlockToBirds
  exists  db/migrate
  create  db/migrate/002_add_flock_to_birds.rb

codetitle. db/migrate/002_add_flock_to_birds.rb

class AddFlockToBirds < ActiveRecord::Migration
  def self.up
    add_column :birds, :flock_id, :integer
    add_index 'birds', ['flock_id'], :name => 'index_flock_id'
  end

  def self.down
    remove_column :birds, :flock_id
  end
end

Creating the models

codetitle. app/models/flock.rb

class Flock < ActiveRecord::Base
  has_many :birds
end

codetitle. app/models/bird.rb

class Bird < ActiveRecord::Base
  belongs_to :flock
end

Available methods

to be written

Creating a dropdown menu to select a flock

Lets say the user is editing a bird record. We want to allow the user to select which flock the bird is a part of by choosing among the available flocks using a dropdown menu.

Create a helper to return an array of flocks suitable for use in a select:

codetitle. app/helpers/birds_helper.rb

def flocks_for_select
  Flock.find(:all, :order => 'name').collect {|f| [ f.name, f.id ] }
end

This will return an array that looks like this:

[ ["flock of pigeons", 1], ["flock of crows", 2], ["flock of geese", 3] ]

This array is exactly what we need to pass to the select helper in order to populate the dropdown menu:

codetitle. app/views/birds/edit.rhml

<% form_tag(:action => "update", :id => @bird.id) do %>
  <%= select("bird", "flock_id", flocks_for_select, {:include_blank => true}) %>
  <%= submit_tag 'update' %>
<% end %>

Create corresponding code in the controller:

codetitle. app/controllers/birds_controller.rb

def update
  @bird = Bird.find(params[:id])
  @bird.flock_id = params[:bird][:flock_id]
  @bird.save
end