Ruby on Rails 之旅(七)—— Ruby on Rails 入门(2)

Active Record objects don‘t specify their attributes directly, but rather infer them from the table definition with which they‘re linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.

本章就来学习一下ROR的特色的ActiveRecord

用下面语句创建一个model名字叫event,具有name,description,is_public,capacity属性。

script/generate model event name:string description:text is_public:boolean capacity:integer

接下来创建表

rake db:migrate

查看一下DB中是否成功创建event表

接下来用一组命令语句来展示一下(script/console):

>> event = Event.new
event = Event.new
=> #<Event id: nil, name: nil, description: nil, is_public: nil, capacity: nil, created_at: nil, updated_at: nil>
>> event.name = "Ruby course"
event.name = "Ruby course"
=> "Ruby course"
>> event.description = "fooobarrrrr"
event.description = "fooobarrrrr"
=> "fooobarrrrr"
>> event.save
event.save
=> true
>> event.id
event.id
=> 1
>> e = Event.find(1)
e = Event.find(1)
=> #<Event id: 1, name: "Ruby course", description: "fooobarrrrr", is_public: nil, capacity: nil, created_at: "2010-08-11 07:42:15", updated_at: "2010-08-11 07:42:15">
>> e = Event.find_by_name("Ruby course")
e = Event.find_by_name("Ruby course")
=> #<Event id: 1, name: "Ruby course", description: "fooobarrrrr", is_public: nil, capacity: nil, created_at: "2010-08-11 07:42:15", updated_at: "2010-08-11 07:42:15">
>> e = Event.find(:first, :conditions => { :name => "Ruby course" })
e = Event.find(:first, :conditions => { :name => "Ruby course" })
=> #<Event id: 1, name: "Ruby course", description: "fooobarrrrr", is_public: nil, capacity: nil, created_at: "2010-08-11 07:42:15", updated_at: "2010-08-11 07:42:15">
>> e = Event.find(:first, :conditions => ["name = ?", "Ruby course"])
e = Event.find(:first, :conditions => ["name = ?", "Ruby course"])
=> #<Event id: 1, name: "Ruby course", description: "fooobarrrrr", is_public: nil, capacity: nil, created_at: "2010-08-11 07:42:15", updated_at: "2010-08-11 07:42:15">
>> e.name
e.name
=> "Ruby course"
>> e.update_attributes( :name => 'abc', :is_public => false )
e.update_attributes( :name => 'abc', :is_public => false )
=> true
>> e.destroy
e.destroy
=> #<Event id: 1, name: "abc", description: "fooobarrrrr", is_public: false, capacity: nil, created_at: "2010-08-11 07:42:15", updated_at: "2010-08-11 07:43:01">
>> Event.find(:all, :limit => 2, :order => 'id DESC')
Event.find(:all, :limit => 2, :order => 'id DESC')
=> []
>> 

注意观察过程,及语法特点。

model的基本应用学会之后,我们来学一下Model Validation

编辑:/app/models/event.rb

class Event < ActiveRecord::Base
    validates_presence_of :name
end

离开 console 重新进入,或者执行 reload!

>> event = Event.new
event = Event.new
=> #<Event id: nil, name: nil, description: nil, is_public: nil, capacity: nil, created_at: nil, updated_at: nil>
>> event.save
event.save
=> false
>> event.errors.full_messages
event.errors.full_messages
=> ["Name can't be blank"]
>> event.name = 'ihower'
event.name = 'ihower'
=> "ihower"
>> event.save
event.save
=> true
>> 

看来,我们刚才追加的Validation已经生效了。

接下来不适用脚手架来创建一套CRUD应用。

script/generate controller events

编辑文件:app/controllers/events_controller.rb

  def index
    @events = Event.find(:all)
  end
 
  def show
    @event = Event.find(params[:id])
  end
  
  def new
    @event = Event.new
  end
  
  def create
    @event = Event.new(params[:event])
    @event.save
    
    redirect_to :action => :index
  end
  
  def edit
    @event = Event.find(params[:id])
  end
  
  def update
    @event = Event.find(params[:id])
    @event.update_attributes(params[:event])
    
    redirect_to :action => :show, :id => @event
  end
  
  def destroy
    @event = Event.find(params[:id])
    @event.destroy
    
    redirect_to :action => :index
  end

新增:/app/views/events/index.html.erb

    <ul>
      <% @events.each do |event| %>
      <li>
        <%= link_to event.name, :controller => 'events',
        :action => 'show', :id => event %>
        <%= link_to 'edit', :controller => 'events',
        :action => 'edit', :id => event %>
        <%= link_to 'delete', :controller => 'events',
        :action => 'destroy', :id => event %>
      </li>
      <% end -%>
    </ul>
    <%= link_to 'new event', :controller => 'events', :action => 'new' %>

新增:/app/views/events/show.html.erb

    <%=h @event.name %>
    <%=h @event.description %>
    <p>
      <%= link_to 'back to index', :controller => 'events',
      :action => 'index' %>
    </p>

新增:/app/views/events/new.html.erb

    <% form_for @event, :url => { :controller => 'events',
    :action => 'create' } do |f| %>
    <%= f.label :name, "Name" %>
    <%= f.text_field :name %>
    <%= f.label :description, "Description" %>
    <%= f.text_area :description %>
    <%= f.submit "Create" %>
    <% end %>

新建:/app/views/events/edit.html.erb

<% form_for @event, :url => { :controller => 'events',
:action => 'update', :id => @event } do |f| %>
<%= f.label :name, "Name" %>
<%= f.text_field :name %>
<%= f.label :description, "Description" %>
<%= f.text_area :description %>
<%= f.submit "Update" %>
<% end %>

 

访问网址:http://localhost:3000/events

看看是不是已经看到没有任何样式的画面了。

画面样式如何加呢?每个画面引入?太老土了。看看ROR的做法:

新建:/app/views/layout/application.html.erb

 

<!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>Posts: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body style="background: #EEEEEE;">

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

<%= yield  %>

</body>
</html>

在刷新一下画面,呵呵~是不是变成灰色背景了?这说明已经剩下了。

如果你还有其他的controller可以看看是不是都变色了。

这个是全局设置。如果想知识应用到events怎么做呢?

很简单,创建的文件名application.html.erb->events.html.erb

再看看,是不是只有events下的文件生效了呢。

很方便吧。


接下来看看flash

  1. 在 create action 中加入 flash[:notice] = "创建成功"
  2. 在 update action 中加入 flash[:notice] = "修改成功"
  3. 在 destroy action 中加入 flash[:notice] = "删除成功"

 

然后用画面跑一边所有应用,是不是对应的成功消息都打印出来了。

下面来看看部分模板(Partial template)的使用方法:

new.html.erb edit.html.erb 的窗体程序移往 _form.html.erb,内容如下

<%= f.label :name, "Name" %>
<%= f.text_field :name %>
<%= f.label :description, "Description" %>
<%= f.text_area :description %>

new.html.erb edit.html.erb 的窗体内加回

<%= render :partial => 'form', :locals => { :f => f } %>

再跑一圈画面,应该还是跟之前一样的,说明编辑和创建画面已经成功的应用了模板文件了。

 

再来看看before_filter

在 events_controller.rb 中加入:

before_filter :find_event, :only => [ :show, :edit, :update, :destroy]

 

 

创建下面方法:

  protected
  def find_event
    @event = Event.find(params[:id])
  end 

删除 show, edit, update, destroy 方法中的 @event = Event.find(params[:id])

这样就达到了在执行show, edit, update, destroy等几个方法前都共同调用了find_event方法,并把值保存在实例变量中。

 

下面接续学习Model validation

编辑 /app/models/event.rb 加入 

 

validates_presence_of :name

修改/app/controllers/events.rb 的 create 和 update 方法

  def create
    @event = Event.new(params[:event])
    
    if @event.save
      flash[:notice] = "创建成功"
      redirect_to :action => :index
    else
      render :action => :new
    end
    
  end

  def update
    
    if @event.update_attributes(params[:event])
      flash[:notice] = "修改成功"
      redirect_to :action => :show, :id => @event
    else
      render :action => :edit
    end  
    
  end

编辑 new.html.erb edit.html.erb 加入

<%= error_messages_for :event %>

 

回到画面上,在编辑画面或者新建画面中不输入名字,然后点保存,会看到下面的样子:

Ruby on Rails 之旅(七)—— Ruby on Rails 入门(2)

说明生效了。

常用的功能还有分页,让我们组装一下:

script/plugin install git://github.com/mislav/will_paginate

windows下默认没有安装git,到这里下载:http://code.google.com/p/msysgit/downloads/list

然后就可以使用上面的语句安装了。

安装完之后,修改 /app/controllers/events_controller.rb 的 index 方法如下:

 

def index
 @events = Event.paginate(:page => params[:page], :per_page => 3)
end

編輯 /app/views/events/index.html.erb,循环外加入

<%= will_paginate @events %>

添加超过3天数据看看,是不是出现翻页了。

 

 

 



你可能感兴趣的:(git,template,validation,on,Model,Ruby,Rails,partial,paginate)