ruby on rails 入门笔记

1. 环境搭建

·      Ruby1.8.7+ (那么由于187p248249bug可能会导致Rails3崩溃,官方建议使用1.9.2Ruby版本)

·      RubyGems

·      SQLITE3数据库(那么这个数据库是Rails内置支持的,我们也可以使用其他数据库,比如MySql5.5

安装:

1, 安装ruby192, 地址:http://rubyinstaller.org/

2, 安装rails3, $ gem install rails

3, 安装IDE, 个人比较喜欢Aptana3, www.aptana.com

2. Rails的指导原则和理念

·      DRY(Dont RepeatYourself) - 保持代码清晰高效,这个一直是我喜欢rails的原因之一

·      约定大于配置 - rails假定你想要做什么以及准备如何做,而不是把任何事情都放到配置文件中去。比如我们说好数据库表的名称应该是模型类名称的小写的复数形式。那么rails会自动把该数据表与其模型类进行关联。

·      RESTWEB应用的最佳模式 - resources以及标准的HTTP动作来组织你的应用。

 

3. 创建你的第一个应用

大多数的第一个应用要么是购物车要么就是博客, 我们也不能免俗. 我们将要在下面的内容中打造一个博客,也就是rails经常吹嘘的10分钟打造的博客系统(事实上用不了十分钟)

$ rails new blog

这将使rails为你创建一个blog工程 (rails -h可以查看rails命令的帮助)

$ cd blog

我们转到blog目录内。

那么在任何情况下,Rails会在你的工作路径内为你创建一个blog的文件夹。本教程的大多数工作都会在app文件夹内操作,这里有一个Rails默认创建应用时创建的文件夹以及文件说明:

文件/文件夹

说明

Gemfile

该文件允许你指定你程序所需要的gem (比如你用到了mysql数据库, 你需要在这里指定 gem "mysql").

README

你的应用程序大体说明. 用这个来告诉他人该程序是干什么的, 等等.

Rakefile

该文件包含了一系列可以在终端运行的命令.

app/

包含了应用程序的控制器,模型,以及视图. 在本教程中你将专注于该文件夹.

config/

配置你应用程序的运行时规格,路由,数据库等等.

config.ru

基于服务器的Rack配置,用于启动程序.

db/

显示你当前数据库的模式,以及数据库迁移.

doc/

你应用的详细文档.

lib/

你应用的扩展模块.

log/

日志.

public/

唯一可以被访问的文件夹. 你可以保存你的图像,javascript, 样式表(CSS), 以及其他静态文本.

script/

包含启动你程序的rails脚本,并可以放置其他你用来部署或者运行你程序的脚本.

test/

单元测试,夹具以及其他测试

tmp/

临时文件

vendor/

放置第三方代码的地方. 在一个典型的rails应用中, 这将包括ruby gems, rails源代码 (如果你拷贝到你的应用中的话), 以及包含额外功能的插件.

接下来我们安装需要的gems

$ bundle install

(事实上绑定的gems都定义在gemfile中)

配置数据库连接:config/database.yml, 默认情况下是连接到SQLite3的, 如果你在使用SQLite3,保持默认就可以了, 如果是MySql,需要改为:

development:
  adapter: mysql 
  encoding: utf8 
  database: blog_development 
  pool: 5 
  username: root 
  password: root

接下来创建数据库。

$ rake db:create

该rake命令会根据你的数据库配置自动为你创建数据库

万事俱备,只欠服务器了

$ rails s

(新的script命令变化很大, 现在只需要输入 rails [option] [args] 就可以了)

默认情况下 rails 将启动 Webrick 服务器, 赶快打开你的浏览器在地址栏输入http://localhost:3000/ 查看你的第一个rails程序 吧 :)


-----------------------------------------------------------

1.Hello Rails

接下来我们要输出一个所有语言的都要学习的 hello world。

要在rails应用中输出一个hello rails,你需要创建一个控制器以及一个视图。在rails的世界里,你几乎不用手动的一个个去创建各个控制器与视图,rails命令就可以帮忙我们搞定一切。

$ rails g controller home index

rails将根据命令为你创建多个文件,其他包括 app/views/home/index.html.erb, 这是一个用于显示index动作结果的模板,打开该文件,写入以下代码:

<h1>Hello, Rails</h1>

 现在你已经完成了了控制器与视图。在这里,我们需要在访问 localhost:3000 的时候就显示hello rails,首先我们需要删除 public/index.html

$ rm public/index.html

然后你需要告诉rails你实际的首页在什么位置。打开config/routes.rb, 该文件是你应用程序的路由设置,它用指定的DSL(domain-specific language)来保存条目,来告诉rails如何把进来的请求转发到相应的控制器以及动作。该文件包含了许多路由器样例,其他一个就是如何指定控制器和动作来访问根地址。

找到以 root 开头的行,改为如下

 现在你可以在 http://localhost:3000 中看到HelloRails了

 

2. 使用脚手架快速搭建网页

rails的脚手架可以快速生成应用程序的一些片段,如果你需要为一个资源创建一系列的控制器视图模型,那么脚手架就是你需要的工具

 

3. 创建资源

对于一个博客程序,你可以以生成一个Post资源脚手架开始:

$ rails g scaffold postname:string title:string content:text

该命令将为你构建15个文件:

文件

说明

db/migrate/20101122214725_create_posts.rb

创建posts表的迁移任务 (你的文件名称将包括一个不同的时间戳)

app/models/post.rb

Post 模型

test/fixtures/posts.yml

用于测试的posts夹具

app/controllers/posts_controller.rb

Posts控制器

app/views/posts/index.html.erb

posts的首页视图

app/views/posts/edit.html.erb

posts的编辑视图

app/views/posts/show.html.erb

显示单个post的视图

app/views/posts/new.html.erb

创建post的视图

app/views/posts/_form.html.erb

用于编辑与新建post的局部表单模板

app/helpers/posts_helper.rb

post视图的帮助器

test/unit/post_test.rb

post模型的单元测试工具

test/functional/posts_controller_test.rb

posts控制器的功能测试工具

test/unit/helpers/posts_helper_test.rb

posts帮助器的单元测试工具

config/routes.rb

为posts添加路由信息

public/stylesheets/scaffold.css

脚手架的默认CSS

rails generate scaffold 命令产生的其中一个文件就是数据库迁移文件,Migration 是设计用来方便创建和修改数据库的Ruby类。rails使用rake任务来运行迁移。而且 Migration 可以撤销先前应用到数据库内的迁移操作。我们现在来看一下所生成的迁移文件(记住:迁移任务的文件名永远是唯一的):

 上面的迁移创建了2个方法,up 是在你迁移进数据库时调用的,而down是你撤销迁移时用到的。up 命令创建了一个posts表以及2个string列,1个text列,同时它也为表自动创建了2个时间戳列,created_at, update_at 用于记录的创建与更新。下面我们运行数据库迁移任务:

$ rake db:migrate

rails 将执行迁移并告诉你它已经为你创建了posts表

 

4. 添加超链接

下面我们将在首页添加一个到posts的超链接:

 link_to 方法是rails的内置视图帮助器的功能之一,它根据参数创建一段超链接代码

 

现在你可以在浏览器内完成你博客的文章输入了。打开 http://localhost:3000 点击超链接:


rails将转到posts控制器的index动作,现在数据库里还没人任何记录,点击 New post 你可以转到新建post视图然后创建一条记录。之后你会发现你可以编辑,查看,以及删除该记录,而这么多功能只是用了一个 rails generate scaffold 命令来完成的。

 

注意:在development模式下(默认)rails会在每次请求时重新加载你的代码,所以你不必要在每次修改后重启你的服务器。

 

5. 模型

打开模型文件 app/models/post.rb,你会发现里面只是一个空的类:

 实际上远远不是如此,Post类继承了ActiveRecord::Base类,Active Record为你的rails提供了大量的功能,包括基本的数据库CRUD操作,验证操作,复杂的搜索支持以及模型之间的各种关联。

下面我们为post模型添加一些验证:

 这些改动确保了了所有的posts都必须具有name与title属性,并且title必须包含至少5个字符。

要查看动作的验证,你可以使用控制台。控制台可以根据你的上下文环境执行ruby代码:

$ rails c (rails console)

控制台加载完成后, 你可以操作你的模型

irb(main):001:0> p =Post.new(:content => 'a new post')

=> # 

irb(main):002:0> p.save

=> false

irb(main):003:0> p.errors

=> {:name=>["can't beblank"], :title=>["can't be blank", "is too short(minimum is 5 characters)"]}

irb(main):004:0>

该代码显示了创建一个post实例,然后试图保存但是返回了false(也就是保存失败), 然后查看下发生的错误

当你结束控制台,输入exit然后回车就可以了。

注意:与 development 服务器不同,控制台不会自动重载你的代码。所以当你的模型类发生改变时,输入 reload! 来重载代码。

1. 列出所有Posts
要开始查看功能的最简单的地方应该是列举所有记录的代码了。现在我们打开app/controllers/post_controller.rb, 看到 index 方法
def index
    @posts = Post.all
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @posts }
    end
end
实际上在这里有2个地方与rails2不同了,第一是查询的方式,以前我们可能会这样写
@posts =Post.find(:all)
,那么现在这种方式完全改变了,现在多出了一个重要的类ActivaRecord::Relation 在里面分装了大量的数据库相关的操作。第二呢,我们不用写成上面的这种代码了:
respond_to:html,:js,:xml
def index
    @posts = Post.all
    respond_with @posts
end
这样很容易解释,相应的格式请求使用相应的模板,比如我们访问http://localhost:3000/posts.xml 那么我们会得到一个xml格式的posts, 是不是很REST?这里我们加了一个:js,这为后面教程中使用ujs做下铺垫,那么具体的用法我们会在后面教程中给大家一一说明。
Rails把所有该动作中的实例变量传递给相应的视图,这里是app/views/posts/index.html.erb :
<h1>Listingposts</h1>
<table>
  <tr>
    <th>Name</th>
    <th>Title</th>
    <th>Content</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>
<% @posts.each do |post| %>

  <tr>
    <td><%= post.name%></td>
    <td><%= post.title%></td>
    <td><%= post.content%></td>
    <td><%= link_to 'Show', post%></td>
<td><%=link_to 'Edit', edit_post_path(post) %></td>
 <td><%= link_to 'Destroy', post,:confirm => 'Are you sure?', :method
=>:delete %></td>

  </tr>
<% end %>
</table>
<br />
<%=link_to 'New post', new_post_path %>
该视图遍历@posts数组来显示内容以及链接,一些要注意的地方:
·      link_to 绑定了特定的记录操作
·      edit_post_path 与 new_post_path 实际上在你设定 routes.rb 中相关resources的时候就已经给你生成的帮助器(好像一共有7个),你可以在控制器中看到不同的这种帮助器。
这里还有一点值得注意:在先前版本的rails中你可能需要使用 来实现HTML转义,那么在3.0中,默认就已经是转义的了,如果你需要获得未转义的HTML,你需要这样写 (raw我想大家很容易理解, java中也经常有这种警告)
 
2. 自定义布局
当rails渲染视图给浏览器时,它会把视图放置到布局内然后在输出。在先前的rails版本中,railsg scaffold 命令会自动创建控制器指定的布局,比如app/views/layouts/posts.html.erb, 那么在3.0中app/views/layouts/application.html.erb 作用与所有控制器。打开你的编辑器,把该布局修改如下:
<!DOCTYPE html>
<html>
<head>
  <title>Blog</title>
  <%= stylesheet_link_tag :all %>

  <%= javascript_include_tag :defaults%>

  <%= csrf_meta_tag %>

</head>
<body style="background: #EEEEEE;">

 
<%= yield %>

 
</body>
</html>
现在你刷新你的页面你会发现背景变成了灰色。
3. 创建新的Post
创建一个新的Post将调用两个动作,第一个是new,它将初始化一个Post对象。
def new
    @post = Post.new
    respond_with @post
end
(同样我们在这里改为更简单的方式, 是不是很DRY?)
在 new.html.erb 视图中显示一个空的Post给用户:
<h1>Newpost</h1>
<%= render 'form'%>
<%= link_to'Back', posts_path %>
是我们第一次介绍Rails的局部模板。局部模板实际上也是一个视图文件,只是该文件可以被多个视图重复引用。在这种情况下,form可用于创建,更新post,然后我们可以看到app/views/posts/_form.html.erb:
<%=form_for(@post) do |f| %>
  <% if @post.errors.any? %>
    <divid="error_explanation">
      <h2><%=pluralize(@post.errors.count, "error") %> prohibited this postfrom being saved:</h2>
      <ul>
      <%@post.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
   <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :content %><br />
    <%= f.text_area :content %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
局部模板可以同样接受视图的实例变量,当然也可以接受视图传递过来的变量。这里有一个另一种写法。
首先我们先稍微了解一下局部视图。
·      局部视图都以 下划线('_')开头
·      局部视图本事存在一个变量可以传递到局部视图里面,该变量是 去掉下划线,比如我的局部视图是 _form.erb, 那么在局部里面有存在一个 form 的变量, 当然还可以设定其他变量或者集合,这些我们将在后面的教程中详细学习。
现在,我们有一个 @post 变量, 那么我们可以把render 改为, rails很聪明,那么我们在局部视图中就会存在一个post 变量,所以在局部视图中 把所有@post改为post,最后我们还要把 _form.html.erb 改为 _post.html.erb. 大家可以试一下,当然其实在本教程中完全没有必要,我这样说只是在为后面的教程做铺垫,这样大家就会更容易明白。
那么关于局部视图的用法我们会在后面的内容中详细的介绍。
我们现在再来看下 form_for,form_for 用于根据模型对象生成表单。比如f.text_field :name 会告诉rails生成一个文本输入框,并且保存模型的name属性。(实际上生成的是 <input type='text'name='post[name]' />)
实际上 form_for 方法知道你是new还是edit,然后对提交按钮设置相应的value,(比如在这里new里面是createpost, edit里面是updatepost)
 
如果你需要创建与模型无关的表单,可以使用 form_tag 方法
当用户点击 Create Post 按钮时,浏览器将会把表单信息提交给create方法(RAILS知道调用create方法,因为这是POST提交的):
def create

    @post = Post.new(params[:post])
    if @post.save
      respond_with @post, :notice => 'Postwas successfully created.'
    else
      render :action => 'new'

    end
end
create方法根据传递的post参数初始化了一个post对象,保存成功以后放回用户请求的相应格式。然后把用户重定向到show页面并且设置一条成功创建的信息反馈给用户。
 如果post由于验证失败等原因未能成功保存,那么控制器将把用户返回到new页面,并显示相应的错误信息
1. 显示一条Post
当你在index页面点击一条文章的链接时,它将指向一条类似http://localhost:3000/posts/1 的地址。Rails是把它作为show动作资源来解释的,然后传递1 作为:id 的参数。下面是show 动作:
def show
  @post = Post.find(params[:id])
  respond_with @post
end
show方法通过传入id值使用 Post.find来搜索数据库中的单条记录,记录找到之后,Rails使用show.html.erb 视图进行渲染:
<pclass="notice"><%= notice %></p>
<p>
  <b>Name:</b>
  <%= @post.name %>
</p>
 <p>
  <b>Title:</b>
  <%= @post.title %>
</p>
 <p>
  <b>Content:</b>
  <%= @post.content %>
</p>
  <%= link_to 'Edit',edit_post_path(@post) %> |
<%= link_to'Back', posts_path %>
2. 编辑Posts
和创建Post一样,编辑post也是一个两部分处理。第一步请求edit_post_path(@post) , 该方法将调用控制器中的 edit 动作:
def edit
  @post = Post.find(params[:id])
end
找到请求的记录之后,Rails使用edit.html.erb 视图显示出来:
<h1>Editingpost</h1>
 <%= render 'form' %>
<%= link_to'Show', @post %> |
<%= link_to'Back', posts_path %>
和 new 动作一样,Rails使用相同的_form.erb 局部模板,不过这次,该表单将使用PUT 方式到PostsController, 而且提交按钮将显示为 “Update Post”。注意这里的 实际上是 。
提交由该视图创建的表单将调用update 动作:
def update
  @post = Post.find(params[:id])
  if @post.update_attributes(params[:post])
    respond_with @post, :notice => 'Post wassuccessfully updated.'
  else
    render :action => 'edit'
  end
end
在update方法中,首先rails使用:id参数获取数据库中相应的post记录,然后使用update_attributes 来更新表单中的内容到数据库中。如果更新成功,转到 show 页面,如果更新失败,那么重新回到edit 页面。
 3. 删除一条Post
最后,点击一条post的删除链接将请求destroy动作。
def destroy
  @post = Post.find(params[:id])
  @post.destroy
  respond_with @post
end
destroy方法将从数据库中移除相应的记录,然后浏览器将跳转到index 页面。
1. 添加第二个模型
在前面的教程中,我们已经学会的使用脚手架快速搭建一个简单的应用,毕竟脚手架不能做任何事情,现在我们需要在应用中添加第二个模型了。
模型在rails中使用单数形式,而其相关的数据库将使用复数名称。
那么对于一个博客来说,评论总是少不了的,我们现在就要创建一个Comment 模型。对于大多数的rails 程序员来说,一般都是通过rails的生成器来生成模型,在这里我们也一样:
$ rails g model commentcommenter:string body:text post:references
该命令将创建4个文件:
·      app/models/comment.rb – 模型
·      db/migrate/20101128142329_create_comments.rb – 迁移文件
·      test/unit/comment_test.rb and test/fixtures/comments.yml – 测试文件.
首先,我们看一下 comment.rb
class Comment < ActiveRecord::Base
  belongs_to :post
end
 
 初看之下,你可能会觉得它与post模型很相识,不同之处在于它多了一行 belongs_to 声明,而这将会建立它与post模型之间的关联, 那么在后面的教程中我们将详细学习。


同时,Rails还生成了迁移文件来创建相应的表:
class CreateComments< ActiveRecord::Migration

  def self.up

    create_table :comments do |t|
      t.string :commenter
      t.text :body
      t.references :post
      t.timestamps
    end
  end
 
  def self.down
    drop_table :comments

  end
end
 与之前的rails版本不同,这里多了一个t.references 定义。t.references:post 将建立一个posts表的外键post_id, 值得注意的是这里的:post 指的模型而不是表,这点一定要搞清楚。
现在运行迁移操作把:
 
$ rake db:migrate

2. 关联模型
Active Record的关联让你很容易的声明模型之间的关系。对于Posts和Comments,很明显是一对多的关系。
前面rails已经为我们声明了belongs_to 关系,现在我们需要再声明一个has_many 关系,打开post.rb 然后添加下面一行:
class Post <ActiveRecord::Base
  validates :name,  :presence => true
  validates :title, :presence => true,
               :length => { :minimum => 5}
  has_many :comments
end
现在双方都已经建立起一系列的关系,打个比方,假如你有一个实例变量@post 包含一条post,那么你可以使用@post.comments 来检索所有该 post 中的 comment。

3. 为comments添加路由
和home控制器一样,我们需要添加一条路由,这样rails可以知道哪里可以看到评论。再次打开routes.rb 你可以看到上次手脚架自动给posts添加的路由条目,我们编辑下该条目:
resources :posts do
  resources :comments
end
这将使 comments 资源作为posts 资源的嵌套资源。而这也反映出post 与comment 之间的关系。
 
4. 生成控制器
模型有了,现在你需要创建comments控制器了,同样我们使用生成器来创建该控制器:
$ rails g controllercomments

与任何博客一样,我们的读者将在他们阅读文章后直接添加评论,一旦完成评论的添加,他们将跳转到post的show页面,所以,我们的CommnetsController仅需提供创建以及删除垃圾评论的方法即可。
首先,我们修改下post的show.html.erb模板使之可以创建与显示评论:
<pclass="notice"><%= notice %></p> <p>
  <b>Name:</b>
  <%= @post.name %>
</p>
 <p>
  <b>Title:</b>
  <%= @post.title %>
</p>
 
<p>
  <b>Content:</b>
  <%= @post.content %>
</p>
 
<h2>Add a comment:</h2>
<%= form_for([@post,@post.comments.build]) do |f| %>

  <div class="field">

    <%= f.label :commenter %><br/>

    <%= f.text_field :commenter %>

  </div>
  <div class="field">

    <%= f.label :body %><br/>

    <%= f.text_area :body %>

  </div>
  <div class="actions">

    <%= f.submit %>

  </div>
<% end %>

 
<%= link_to 'Edit Post', edit_post_path(@post) %> |

<%= link_to 'Back to Posts', posts_path %> |
 这将在post的show页面中显示一个comment表单来创建评论,而这将调用CommentsController中的create方法,如下:
classCommentsController < ApplicationController

  def create

    @post = Post.find(params[:post_id])

    @comment =@post.comments.create(params[:comment])

    redirect_to  post_path(@post)

  end
end
 
 你可能会发现这里要比之前的posts控制器中稍微复杂一些,这就是你之前设定嵌套的片效应。每一个评论的请求需要追踪该评论所附加的Post,所以find首先会找出该Post对
接下来,代码调用了关联中存在的方法,我们在这里使用create方法来创建并保存该条评论,这将自动关联到对应的post记录。
一旦我们完成了评论的保存,我们就要使用post_path @post 把用户跳转到原来显示该post的show页面。正如我们所看到的,它调用了PostsController中的show方法来渲染show.html.erb 模板。这里我们需要显示所有关于该Post的评论,所以让我们更改下 show.html.erb 页面:
<pclass="notice"><%= notice %></p>
 <p>
  <b>Name:</b>
  <%= @post.name %>
</p>
 
<p>
  <b>Title:</b>
  <%= @post.title %>

</p>
 
<p>
  <b>Content:</b>
  <%= @post.content %>

</p>
 
<h2>Comments</h2>
<% @post.comments.each do |comment| %>

  <p>
    <b>Commenter:</b>
    <%= comment.commenter %>

  </p>
 
  <p>
    <b>Comment:</b>
    <%= comment.body %>

  </p>
<% end %>

 
<h2>Add a comment:</h2>

<%= form_for([@post, @post.comments.build]) do |f| %>

  <div class="field">

    <%= f.label :commenter %><br/>

    <%= f.text_field :commenter %>

  </div>
  <div class="field">

    <%= f.label :body %><br/>

    <%= f.text_area :body %>

  </div>
  <div class="actions">

    <%= f.submit %>

  </div>
<% end %>

 
<br />

 
<%= link_to 'Edit Post', edit_post_path(@post) %> |

<%= link_to 'Back to Posts', posts_path %> |

现在你可以在你的博客中添加post和评论了,并且把它们显示在正确的地方。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值