Rails on Ruby

846 阅读11分钟

介绍

Rails 是使用 Ruby 语言编写的网页程序开发框架,目的是为开发者提供常用组件,简化网页程序的开发。只需编写较少的代码,就能实现其他编程语言或框架难以企及的功能。经验丰富的 Rails 程序员会发现,Rails 让程序开发变得更有乐趣。

Rails 有自己的一套规则,认为问题总有最好的解决方法,而且建议使用最好的方法,有些情况下甚至不推荐使用其他替代方案。学会如何按照 Rails 的思维开发,能极大提高开发效率。如果坚持在 Rails 开发中使用其他语言中的旧思想,尝试使用别处学来的编程模式,开发过程就不那么有趣了。

Rails 哲学包含两大指导思想:

  • 不要自我重复(DRY): DRY 是软件开发中的一个原则,“系统中的每个功能都要具有单一、准确、可信的实现。”。不重复表述同一件事,写出的代码才能更易维护,更具扩展性,也更不容易出问题。

  • 多约定,少配置: Rails 为网页程序的大多数需求都提供了最好的解决方法,而且默认使用这些约定,不用在长长的配置文件中设置每个细节。

Rails生成新程序

对于Rails的安装建议参考:www.tutorialspoint.com/ruby-on-rai…

Rails 提供了多个被称为“生成器”的脚本,可以简化开发,生成某项操作需要的所有文件。其中一个是新程序生成器,生成一个 Rails 程序骨架,不用自己一个一个新建文件。

打开终端,进入有写权限的文件夹,执行以下命令生成一个新程序:

rails new blog

这个命令会在文件夹 blog 中新建一个 Rails 程序,然后执行:

bundle install

安装 Gemfile 中列出的 gem。对于没有翻墙的情况下,安装bundle时候会失败,可以打开Gemfile,修改source的源为国内的源,自己去查找。

source 'https://rubygems.org'

修改后,重新执行:

bundle install

启动Rails service

在命令行执行:

rails s -p 4001

这里-p表示服务的端口号,可以随意设定。rails服务启动后,打开浏览器输入localhost:4001,执行回车,网页上显示如下:

Rails的目录结构

blog 文件夹中有很多自动生成的文件和文件夹,组成一个 Rails 程序,下面简单介绍默认生成的文件和文件夹的作用:

着重介绍

1. app/ :

  • assets/:
    通常放置我们自己为了自己的程序所写的js,css,或者是images文件,分别放在javascripts(js)、stylesheets(CSS)和images文件夹下。主要是用来存放静态文件的地方

  • app/channels/:
    Action Cable中的组件,Action Cable结合WebSockets来实现浏览器端实时的消息通知。一般情况下我们很少使用。

  • app/controllers/:
    rails程序中的控制器文件(Action Controller)一般都存放在这个文件夹下。Action Controller 是 MVC 中的 C(控制器)。路由决定使用哪个控制器处理请求后,控制器负责解析请求,生成对应的请求。Action Controller 会代为处理大多数底层工作,使用易懂的约定,让整个过程清晰明了。
    在大多数按照 REST 规范开发的程序中,控制器会接收请求(开发者不可见),从模型中获取数据,或把数据写入模型,再通过视图生成 HTML。如果控制器需要做其他操作,也没问题,以上只不过是控制器的主要作用。
    因此,控制器可以视作模型和视图的中间人,让模型中的数据可以在视图中使用,把数据显示给用户,再把用户提交的数据保存或更新到模型中。

  • app/helpers/:
    主要用来存放helper方法。在Rails中,Helper指的是可以在Template中使用的辅助方法,主要用途是可以将资料转化成输出用的HTML字串。每个控制器都可以有一个对应的Helper模块,它在app/helper目录下,与控制器文件同名。例如catalog_controller.rb对应的helper文件catalog_helper.rb。当我们希望一个helper方法是全局共享时,通常将该方法放在application_helper.rb中。

  • app/jobs/:
    用来存放任务文件,确保任务文件继承自 ActiveJob::Base即可。
    Active Job 是用来声明任务,并把任务放到多种多样的队列后台中执行的框架。从定期地安排清理,费用账单到发送邮件,任何事情都可以是任务。任何可以切分为小的单元和并行执行的任务都可以用 Active Job 来执行。 Active Job 的目标 主要是确保所有的 Rails 程序有一致任务框架,即便是以 “立即执行”的形式存在。

  • app/mailers/:
    用来存放实现发送邮件功能的文件。
    Rails 使用 Action Mailer 实现发送邮件功能,邮件由邮件程序和视图控制。邮件程序继承自 ActionMailer::Base,作用和控制器类似,保存在文件夹 app/mailers 中,对应的视图保存在文件夹 app/views 中。

  • app/models/:
    用来存放model文件(M层),Rails中用Active Record来实现model的,Active Record 是 MVC 中的 M(模型),处理数据和业务逻辑。Active Record 负责创建和使用需要持久存入数据库中的数据。Active Record 实现了 Active Record 模式,是一种对象关系映射系统。

Active Record 提供了很多功能,其中最重要的几个如下:

    表示模型和其中的数据;
    表示模型之间的关系;
    通过相关联的模型表示继承关系;
    持久存入数据库之前,验证模型;
    以面向对象的方式处理数据库操作;
  • app/views/:
    存放视图的地方(V层),当我们在命令行执行:
rails generate controller users index

的时候,会在app/views文件夹下生成对应的一个文件夹,文件夹名称与控制器名称相同,在此文件夹下即可生成对应控制器的视图文件,例如本例中的app/views/users/index.html.erb文件。

控制器(Controller)

控制器是一个类,继承自 ApplicationController,和其他类一样,定义了很多方法。程序接到请求时,路由决定运行哪个控制器和哪个动作,然后创建该控制器的实例,运行和动作同名的方法。
Rails 控制器的命名习惯是,最后一个单词使用复数形式,但也是有例外,比如 ApplicationController。例如:用 ClientsController,而不是 ClientController;用 SiteAdminsController,而不是 SiteAdminController 或 SitesAdminsController。
在命令行执行:

rails g controller nodes new

命令行运行结果如下:

可以看到,程序会自动帮我们在app/controller下生成一个新的文件叫nodes_controller.rb,对应到app/views/下会帮我们生成一个nodes的文件夹,nodes/文件夹下自动生成一个new_html.erb文件,这个文件就是对应到nodesController中定义的new方法的视图文件。此外,在config/routes.rb文件中会添加 get 'nodes/new'这个路由,这个是用来指定当在客户端通过 ip:port/nodes/new进行http请求时,路由会通过这个直接对应到Controller中的nodes_controller的new方法来进行处理,创建一个 NodesController 实例,运行 new 方法。注意,在上面这段代码中,即使 new 方法是空的也没关系,因为默认会渲染 new.html.erb 视图,除非指定执行其他操作

class NodesController < ApplicationController
  def new
  end
end

详细的Controller介绍,请参考Action Controller 简介

模型(Model)和数据库配置

Active Record 是 MVC 中的 M(模型),处理数据和业务逻辑。Active Record 负责创建和使用需要持久存入数据库中的数据。Active Record 实现了 Active Record 模式,是一种对象关系映射系统。也就是在Rails中我们只需要通过代码生成Active Record模型,Rails会自动把模型映射到数据库(Sqlite、MySQL、Postgresql、Mongdb等等)中的数据表,不需要我们书写操作数据库的SQL语句,就能实现对数据库的增删改查等功能。

多约定少配置:
使用其他编程语言或框架开发程序时,可能必须要编写很多配置代码。大多数的 ORM 框架都是这样。但是,如果遵循 Rails 的约定,创建 Active Record 模型时不用做多少配置(有时甚至完全不用配置)。Rails 的理念是,如果大多数情况下都要使用相同的方式配置程序,那么就应该把这定为默认的方法。所以,只有常规的方法无法满足要求时,才要额外的配置。

命名约定
默认情况下,Active Record 使用一些命名约定,查找模型和数据表之间的映射关系。Rails 把模型的类名转换成复数,然后查找对应的数据表。例如,模型类名为 Book,数据表就是 books。Rails 提供的单复数变形功能很强大,常见和不常见的变形方式都能处理。如果类名由多个单词组成,应该按照 Ruby 的约定,使用驼峰式命名法,这时对应的数据表将使用下划线分隔各单词。因此:

数据表名:复数,下划线分隔单词(例如 book_clubs)
模型类名:单数,每个单词的首字母大写(例如 BookClub)

模式约定:
根据字段的作用不同,Active Record 对数据表中的字段命名也做了相应的约定:

外键 - 使用 singularized_table_name_id 形式命名,例如 item_id,order_id。创建模型关联后,Active Record 会查找这个字段;
主键 - 默认情况下,Active Record 使用整数字段 id 作为表的主键。使用 Active Record 迁移创建数据表时,会自动创建这个字段;

还有一些可选的字段,能为 Active Record 实例添加更多的功能:

created_at - 创建记录时,自动设为当前的时间戳;
updated_at - 更新记录时,自动设为当前的时间戳;
lock_version - 在模型中添加乐观锁定功能;
type - 让模型使用单表继承;
(association_name)_type - 多态关联的类型;
(table_name)_count - 缓存关联对象的数量。例如,posts 表中的 comments_count 字段,缓存每篇文章的评论数;

数据库配置

Rails对数据库的支持非常全面,

Rails中数据库的配置文件在config/database.yml中,Rails默认使用sqlite作为数据库,可以在Gemfile中看到:

Gemfile 是我们创建的一个用于描述 gem 之间依赖的文件。gem 是一堆 Ruby 代码的集合,它能够为我们提供调用。你的 Gemfile 必须放在项目的根目录下面, 这是 Bundler 的要求,对于任何的其他形式的包管理文件来说,这也是标准。这里值得注意的一点是 Gemfile 会被作为 Ruby 代码来执行。当在 Bundler 上下文环境中被执行的时能使我们访问一些方法,我们用这些方法来解释 gem 之间的 require 关系。
可以看到,Gemfile中数据库依赖sqlite3,这里是告诉bundle帮我们安装要依赖的数据库文件,数据库的配置在config/database.yml中,下面是Rails中默认的配置参数:
如果你想用其他的数据库(比如:MySQL、Postgresql等),首先需要再Gemfile中添加依赖的数据库名(postgresql是gem 'pg'),然后在config/database.yml中修改对应的配置文件,例如我这里用postgresql数据库的配置文件,这个文件下的development、test、production分别表示开发环境、测试环境、生产环境下的数据库配置:

Gemfile和database.yml配置文件修改好之后,因为我们修改了Gemfile,所以需要在命令行执行:

bundle install

创建数据库

在执行rake db:create创建在database.yml中配置的数据库之前,需要先在数据库中创建user和对应的password。 在命令行执行:

sudo -u postgres psql
create user username with encrypted password 'password';

其中,username和password分别表示要创建的用户和对应的密码。这个用户名和密码要和database.yml一致。 然后,在命令行执行:

rake db:create

正确执行结果,命令行显示:

创建模型(Model)

通过rails命令创建模型,可以通过rails help查看rails中的命令 这里需要注意,与controller不同的是,在创建model时,model的文件名是单数,而controller是复数,然后在生成的model文件中会自动被转换成复数格式

rails g model user

rails会帮我们创建一个移植的文件(在db/migrate/下),创建一个model文件(app/models/下)

  • 数据表移植文件
    那么,我们就可以在移植文件中添加模型的其他字段,rails自动帮我们创建timestamps字段。 我们在移植文件中添加了两个字段:
    然后,在命令行执行:
rake db:migrate

在数据库表中生成相应的字段。

  • 模型文件
    上面我们已经创建了user的模型,现在可以在终端测试user的模型:在命令行执行:
rails console
User
User.create username: '343', password: '123456'

命令行结果如下:

表明我们已经成功创建模型user,并且数据库中生成了相应的数据表,通过rails的模型进行数据库的增删改查非常方便。