Tuesday, March 20, 2007

How to create drop down boxes in Ruby on Rails

Migration file : 001_create_people.rb

class CreatePeople < ActiveRecord::Migration
def self.up
create_table :people do |t|
t.column :first_name, :string
t.column :last_name, :string
t.column :email, :string
t.column :created_at, :datetime
end
end

def self.down
drop_table :people
end
end

person.rb
class Person < ActiveRecord::Base
has_many :tasks
end

task.rb
class Task < ActiveRecord::Base
belongs_to :user

def self.find_all_person
Person.find(:all, :order => "first_name").map {|u| [u.first_name, u.id] }
end

end

tasks/_form.rhtml

<h2> Create a Task for a Person</h2>
<% form_for ( :task, :url => path, :html => { :method => method } ) do |f| %>
    <p>
    
Title:        <br>
        <%= f.text_field :title, :class => 'text_field' %><br>
    </p>
    <p>
    
Content:
        <br>
        <%= f.text_field :content, :class => 'text_field' %><br>
    </p>

        <br>
        
        <p>Select a priority:
    
          <%= f.select ( :priority, %w { 1 2 3 4 5 6 7 8 9 10 } ) %>
    
        </p>
    </p>

    Person:
            <br>
            <%=
             f.select ( :people_id, @people )
            %>

        </p>
    
    <p>
        <%= submit_tag button_text %>
    </p>

<% end %>

tasks/edit.rhtml
<h1>Editing task</h1>

<%= error_messages_for :task %>

<% form_for ( :task, :url => task_path ( @task ) , :html => { :method => :put } ) do |f| %>
  <p>
    <%= submit_tag "Update" %>
  </p>
<% end %>

<%= link_to 'Show', task_path ( @task ) %> |
<%= link_to 'Back', tasks_path %>

tasks/index.rhtml
<h1>Listing tasks</h1>

<table>
  <tr>
  </tr>
  
<% for task in @tasks %>

<tr>
    <td><%= link_to   ( h task.title ) ,    task_path ( task ) %></td>
  </tr>

<% end %>
</table>

<br />

<%= link_to 'New task', new_task_path %>

tasks/new.rhtml
<h1>New task</h1>

<%= error_messages_for :task %>

<%= render :partial => 'form', :locals => { :path => tasks_path,
                                              :method => :post,
                                              :button_text => 'Create' } %>
                                            

<%= link_to 'Back', tasks_path %>

tasks/show.rhtml

<h2>Task </h2>
    <p> Title: <%=  h @task.title %></p>
    <p>Content: <%= h @task.content %></p>
    <p>Priority: <%= h @task.priority %></p>
    <p>Created At: <%= @task.created_at %></p>
    <p>Person: <%=  @person.first_name %></p> -->
    
<%= link_to 'Back', tasks_path %>

people/_form.rhtml

<% form_for ( :person, :url => path, :html => { :method => method } ) do |f| %>
    <p>
    
    <strong>First Name: </strong>
        <br>
        <%= f.text_field :first_name, :class => 'text_field' %><br>
    </p>
    <p>
    
    <strong>Last Name: </strong>
        <br>
        <%= f.text_field :last_name, :class => 'text_field' %><br>
    </p>

    <strong>Email: </strong>
        <br>
        <%= f.text_field :email, :class => 'text_field' %><br>
    </p>

    <p>
        <%= submit_tag button_text %>
    </p>

<% end %>

people/edit.rhtml
<h1>Editing person</h1>

<%= error_messages_for :person %>

<%= render :partial => 'form', :locals => { :path => person_path ( @person ) ,
                                            :method => :put,
                                            :button_text => 'Update' }
%>


<%= link_to 'Show', person_path ( @person ) %> |
<%= link_to 'Back', people_path %>

people/index.rhtml
<h1>Listing people</h1>
* Create an application to track a person's tasks. The user should be able to
create people, create tasks, and assign a task to a person when the task is created.

<table>
  <tr>
  </tr>
  
<% for person in @people %>
<tr>
    <td><%= link_to   ( h person.first_name ) ,    person_path ( person ) %></td>
  </tr>
  
<% end %>
</table>

<br />

<%= link_to 'New person', new_person_path %>

people/new.rhtml
<h1>New person</h1>

<%= error_messages_for :person %>

<%= render :partial => 'form', :locals => { :path => people_path,
                                              :method => :post,
                                              :button_text => 'Create' } %>


<%= link_to 'Back', people_path %>

people/show.rhtml

<h2>Person </h2>
    <p>First Name: <%=  h @person.first_name %></p>
    <p>Last Name: <%= h @person.last_name %></p>
    <p>Last Name: <%= h @person.email %></p>

<%= link_to 'Edit', edit_person_path ( @person ) %> |
<%= link_to 'Back', people_path %>

home/index.rhtml
<%= link_to  "People",    :controller => :people, :action => :index %><br>
<%= link_to  "Tasks",    :controller => :tasks, :action => :index %>

layouts/people.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>People: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>

<p style="color: green"><%= flash[:notice] %></p>

<%= yield  %>

</body>
</html>

layouts/tasks.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Tasks: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>

<p style="color: green"><%= flash[:notice] %></p>

<%= yield  %>

</body>
</html>

controllers/home_controller.rb
class HomeController < ApplicationController
def index

end
end

people_controller.rb
class PeopleController < ApplicationController
# GET /people
# GET /people.xml
def index
@people = Person.find(:all)

respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => @people.to_xml }
end
end

# GET /people/1
# GET /people/1.xml
def show
@person = Person.find(params[:id])

respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => @person.to_xml }
end
end

# GET /people/new
def new
@person = Person.new
end

# GET /people/1;edit
def edit
@person = Person.find(params[:id])
end

# POST /people
# POST /people.xml
def create
@person = Person.new(params[:person])

respond_to do |format|
if @person.save
flash[:notice] = 'Person was successfully created.'
format.html { redirect_to person_url(@person) }
format.xml { head :created, :location => person_url(@person) }
else
format.html { render :action => "new" }
format.xml { render :xml => @person.errors.to_xml }
end
end
end

# PUT /people/1
# PUT /people/1.xml
def update
@person = Person.find(params[:id])

respond_to do |format|
if @person.update_attributes(params[:person])
flash[:notice] = 'Person was successfully updated.'
format.html { redirect_to person_url(@person) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @person.errors.to_xml }
end
end
end

# DELETE /people/1
# DELETE /people/1.xml
def destroy
@person = Person.find(params[:id])
@person.destroy

respond_to do |format|
format.html { redirect_to people_url }
format.xml { head :ok }
end
end
end

controllers/tasks_controller.rb
class TasksController < ApplicationController
# GET /tasks
# GET /tasks.xml
def index
@tasks = Task.find(:all)

respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => @tasks.to_xml }
end
end

# GET /tasks/1
# GET /tasks/1.xml
def show
@task = Task.find(params[:id])
@person = Person.find(:first, :conditions => "id = #{@task.people_id}")

respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => @task.to_xml }
end
end

# GET /tasks/new
def new
@task = Task.new
@people = Task.find_all_person
end

# GET /tasks/1;edit
def edit
@task = Task.find(params[:id])
end

# POST /tasks
# POST /tasks.xml
def create
@task = Task.new(params[:task])
@person = Person.find(:first, :conditions => "id = #{@task.people_id}")

respond_to do |format|
if @task.save
flash[:notice] = 'Task was successfully created.'
format.html { redirect_to task_url(@task) }
format.xml { head :created, :location => task_url(@task) }
else
format.html { render :action => "new" }
format.xml { render :xml => @task.errors.to_xml }
end
end
end

# PUT /tasks/1
# PUT /tasks/1.xml
def update
@task = Task.find(params[:id])

respond_to do |format|
if @task.update_attributes(params[:task])
flash[:notice] = 'Task was successfully updated.'
format.html { redirect_to task_url(@task) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @task.errors.to_xml }
end
end
end

# DELETE /tasks/1
# DELETE /tasks/1.xml
def destroy
@task = Task.find(params[:id])
@task.destroy

respond_to do |format|
format.html { redirect_to tasks_url }
format.xml { head :ok }
end
end
end

2 comments:

  1. regarding episode 84 (creating a dropdown box with integers)... Why not just do:

    (% select_tag "integers", options_for_select((0..100).to_a, 0), {} %)

    ?

    ReplyDelete
  2. Anonymous6:53 AM

    Yeah... NEWBIE ALERT!

    Could you add by-line comments? :)

    Thank you!

    ReplyDelete