如何在 Ubuntu 22.04 上构建 Ruby on Rails 应用程序
介绍
红宝石。它采用固执己见的应用程序开发方法,假设设定的约定最适合有共同目标的开发人员。因此,Rails 提供了处理路由、有状态数据、资产管理等的约定,以提供大多数 Web 应用程序所需的基线功能。
Rails 遵循不必要的重复。
在本教程中,您将构建一个 Rails 应用程序,使用户能够发布有关鲨鱼及其行为的信息。该项目将作为未来应用程序开发的起点。
先决条件
要学习本教程,您需要:
- 一台运行 Ubuntu 22.04 的本地机器或开发服务器。您的开发机器应该有一个具有管理权限的非 root 用户和配置有
ufw
的防火墙。有关如何设置的说明,请阅读我们的 Ubuntu 22.04 初始服务器设置教程。 - 如何在 Ubuntu 22.04 上安装 Node.js。
- Ruby,如何在 Ubuntu 22.04 上使用 rbenv 安装 Ruby on Rails。本教程使用 Ruby 3.2.0、rbenv 1.2.0-52 和 Rails 7.0.4。
安装了 Node.js、Ruby、rbenv 和 Rails 后,您就可以为应用程序安装数据库了。
第 1 步 — 安装 SQLite3
在创建 Rails shark 应用程序之前,您需要一个数据库来存储用户数据。 Rails 默认配置为使用 SQLite,这在开发中通常是一个不错的选择。由于应用程序数据不需要高级编程可扩展性,SQLite 将满足应用程序的需求。
首先,在您的终端内,更新您的包索引:
- sudo apt update
接下来,安装 sqlite3
和 libsqlite3-dev
包:
- sudo apt install sqlite3 libsqlite3-dev
这将安装 SQLite 及其所需的开发文件。
可以查看版本确认是否安装成功:
- sqlite3 --version
Output3.37.2 2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5dalt1
安装 SQLite 后,您就可以开始开发您的应用程序了。
第 2 步 — 创建一个新的 Rails 项目
安装数据库后,您可以创建一个新的 Rails 项目并访问 Rails 使用 rails new
命令提供的一些默认样板代码。
使用以下命令创建一个名为 sharkapp
的项目:
- rails new sharkapp
输出表明 Rails 正在为您的新项目创建的所有不同内容。以下输出突出显示了一些重要的文件、目录和命令:
Output create
. . .
create Gemfile
. . .
create app
. . .
create app/controllers/application_controller.rb
. . .
create app/models/application_record.rb
. . .
create app/views/layouts/application.html.erb
. . .
create config
create config/routes.rb
create config/application.rb
. . .
create config/environments
create config/environments/development.rb
create config/environments/production.rb
create config/environments/test.rb
. . .
create config/database.yml
create db
create db/seeds.rb
. . .
run bundle install
. . .
Bundle complete! 15 Gemfile dependencies, 69 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
. . .
以下是创建的一些 Rails 文件和文件夹的简要说明:
Gemfile
:此文件列出了您的应用程序的 gem 依赖项。 gem 是一个 Ruby 软件包,而 Gemfile 允许您管理项目的软件需求。app
:app
目录是您的主要应用程序代码所在的目录。这包括构成应用程序本身的模型、控制器、视图、资产、助手和邮件程序。 Rails 为 MVC 模型提供了一些应用程序级的样板文件,例如app/models/application_record.rb
、app/controllers/application_controller.rb
和app/views/layouts/application.html.erb
.config
:此目录包含应用程序的配置设置:config/routes.rb
:您的应用程序的路由声明位于此文件中。config/application.rb
:您的应用程序组件的常规设置位于此文件中。
最后,Rails 运行
bundle install
命令来安装Gemfile
中列出的依赖项。一切设置完成后,导航到新的
sharkapp
目录:- cd sharkapp
在 sharkapp 目录中,使用
rails server
命令启动 Rails 服务器以确保您的应用程序正常运行。如果您在本地计算机上工作,请输入以下代码以启动您的服务器:- rails server
Rails 默认绑定到
localhost
,这意味着您可以通过在浏览器中导航到locahost:3000
来访问您的应用程序:如果您在开发服务器上工作,请首先确保端口
3000
上允许连接:- sudo ufw allow 3000
然后使用
--binding
标志启动服务器,以绑定到您的服务器 IP 地址:- rails server --binding=your_server_ip
在浏览器中导航到
http://your_server_ip:3000
,以访问默认的 Rails 登录页面。准备就绪后,您可以通过在终端中按
CTRL+C
来停止服务器。创建并准备好应用程序后,您就可以开始从 Rails 样板构建以创建独特的应用程序。
第 3 步 — 搭建应用程序的脚手架
要创建 shark 应用程序,您需要创建一个模型来管理您的应用程序数据、视图以允许用户与该数据进行交互,以及一个控制器 管理模型和视图之间的通信。要构建它们,请使用
rails generate scaffold
命令。这将为应用程序生成一个模型、一个创建、读取、更新和删除 (CRUD) 操作,以及用于部分、帮助程序和测试的模板。generate scaffold
命令在后台执行许多操作。该命令包括模型名称和数据库表中所需的字段。 Rails 使用 Ruby 类,同时也继承了ActiveRecord::Base
类。这意味着您可以像使用 Ruby 类一样使用模型类。此外,您还可以从 Active Record 中提取方法。 Active Record 确保将每个类映射到数据库中的一个表,并将该类的每个实例映射到该表中的一行。运行以下命令生成
Shark
模型、控制器和相关视图:- rails generate scaffold Shark name:string facts:text
此命令中的
name:string
和facts:text
选项指示您在数据库表中创建的字段以及它们应接受的数据类型。两者都为您提供了输入所需内容的空间。text
选项允许更多字符。输入此命令后,输出显示生成的所有不同文件:
Outputinvoke active_record create db/migrate/20190804181822_create_sharks.rb create app/models/shark.rb . . . invoke resource_route route resources :sharks invoke scaffold_controller create app/controllers/sharks_controller.rb invoke erb create app/views/sharks create app/views/sharks/index.html.erb create app/views/sharks/edit.html.erb create app/views/sharks/show.html.erb create app/views/sharks/new.html.erb create app/views/sharks/_form.html.erb . . .Rails 在
app/models/shark.rb
中创建了模型并进行了数据库迁移:db/migrate/20190804181822_create_sharks.rb
.迁移文件上的时间戳将与示例输出不同。它还创建了一个控制器
app/controllers/sharks_controller.rb
,以及与应用程序的 CRUD 操作相关的视图,这些视图收集在app/views/sharks
下。在这些视图中有一个部分_form.html.erb
,它包含跨视图使用的代码。最后,Rails 向
config/routes.rb
添加了一个新的资源路由resources :sharks
。这使 Rails 路由器能够将传入的 HTTP 请求与sharks
控制器及其相关视图相匹配。尽管 Rails 已经完成了构建应用程序代码的大部分工作,但还是值得深入研究一些文件以更好地了解正在发生的事情。
要了解控制器文件,请在终端中输入以下命令:
- cat app/controllers/sharks_controller.rb
Outputclass SharksController < ApplicationController before_action :set_shark, only: %i[ show edit update destroy ] # GET /sharks or /sharks.json def index @sharks = Shark.all end # GET /sharks/1 or /sharks/1.json def show end # GET /sharks/new def new @shark = Shark.new end # GET /sharks/1/edit def edit end # POST /sharks or /sharks.json def create @shark = Shark.new(shark_params) respond_to do |format| if @shark.save format.html { redirect_to shark_url(@shark), notice: "Shark was successfully created." } format.json { render :show, status: :created, location: @shark } else format.html { render :new, status: :unprocessable_entity } format.json { render json: @shark.errors, status: :unprocessable_entity } end end end # PATCH/PUT /sharks/1 or /sharks/1.json def update respond_to do |format| if @shark.update(shark_params) format.html { redirect_to shark_url(@shark), notice: "Shark was successfully updated." } format.json { render :show, status: :ok, location: @shark } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @shark.errors, status: :unprocessable_entity } end end end # DELETE /sharks/1 or /sharks/1.json def destroy @shark.destroy respond_to do |format| format.html { redirect_to sharks_url, notice: "Shark was successfully destroyed." } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_shark @shark = Shark.find(params[:id]) end # Only allow a list of trusted parameters through. def shark_params params.require(:shark).permit(:name, :facts) end end控制器负责管理信息如何被获取并传递给它的相关模型,以及它如何与特定视图相关联。例如,
sharks
控制器包含一系列大致映射到标准 CRUD 操作的方法。有比 CRUD 函数更多的方法,可以在出错的情况下提高效率。例如,考虑
create
方法:. . . def create @shark = Shark.new(shark_params) respond_to do |format| if @shark.save format.html { redirect_to @shark, notice: 'Shark was successfully created.' } format.json { render :show, status: :created, location: @shark } else format.html { render :new } format.json { render json: @shark.errors, status: :unprocessable_entity } end end end . . .
如果成功保存了
Shark
类的新实例,redirect_to
将生成一个新请求,然后将其定向到控制器。这是一个GET
请求,它将由show
方法处理,该方法将向用户显示他们最近添加的输入。如果出现故障,Rails 将再次呈现
app/views/sharks/new.html.erb
模板,而不是向路由器发出另一个请求,从而为用户提供另一个提交数据的机会。除了
sharks
控制器之外,Rails 还为index
视图创建了一个模板,它映射到控制器中的index
方法。您将使用它作为应用程序的根视图。运行以下命令输出文件:
- cat app/views/sharks/index.html.erb
Output<p style="color: green"><%= notice %></p> <h1>Sharks</h1> <div id="sharks"> <% @sharks.each do |shark| %> <%= render shark %> <p> <%= link_to "Show this shark", shark %> </p> <% end %> </div> <%= link_to "New shark", new_shark_path %>index
视图循环遍历Shark
类的实例,它映射到数据库中的sharks
表。使用 ERB 模板,视图输出表中与单个鲨鱼实例关联的每个字段:name
和facts
。当您使用
rails generate scaffold
命令定义sharks
足智多谋的路由时,该视图会使用您可用的助手。new
视图使用所谓的局部视图。运行以下命令以返回app/views/sharks/new.html.erb
模板:- cat app/views/sharks/new.html.erb
Output<h1>New shark</h1> <%= render "form", shark: @shark %> <br> <div> <%= link_to "Back to sharks", sharks_path %> </div>尽管此模板可能看起来缺少新鲨鱼条目的输入字段,但对
render form
的引用表明该模板正在拉入_form.html.erb
部分,它提取跨视图重复的代码。输出
_form.html.erb
文件以更全面地了解如何创建新的 shark 实例:- cat app/views/sharks/_form.html.erb
Output<%= form_with(model: shark) do |form| %> <% if shark.errors.any? %> <div style="color: red"> <h2><%= pluralize(shark.errors.count, "error") %> prohibited this shark from being saved:</h2> <ul> <% shark.errors.each do |error| %> <li><%= error.full_message %></li> <% end %> </ul> </div> <% end %> <div> <%= form.label :name, style: "display: block" %> <%= form.text_field :name %> </div> <div> <%= form.label :facts, style: "display: block" %> <%= form.text_area :facts %> </div> <div> <%= form.submit %> </div> <% end %>此模板使用表单助手。表单助手旨在促进使用特定模型的字段和范围从用户输入创建新对象。在此示例中,
form_with
将model: shark
作为参数,它创建的新表单构建器对象具有与sharks
中的字段相对应的字段输入表。这意味着用户可以在表单字段中输入鲨鱼name
和 sharkfacts
。提交此表单将创建一个包含用户数据的 JSON 响应,您的应用程序的其余部分可以通过 params 方法访问该数据。这将使用该数据创建一个
ActionController::Parameters
对象。现在您知道了
rails generate scaffold
为您生成了什么,您可以继续为您的应用程序设置根视图。第 4 步 — 创建应用程序根视图和测试功能
理想情况下,您希望应用程序的登录页面映射到应用程序的根目录,以便用户可以立即了解应用程序的用途。
例如,您可以创建一个
Welcome
控制器和一个关联的index
视图,这为用户提供了一个通用的登录页面,该页面也可以链接到应用程序的不同部分。要进行此设置,您需要修改
config/routes.rb
中的路由设置以指定应用程序的根目录。打开
config/routes.rb
进行编辑,使用nano
或您喜欢的编辑器:- nano config/routes.rb
Rails.application.routes.draw do resources :sharks # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Defines the root path route ("/") # root "articles#index" end
如果不设置更具体的内容,
http://localhost:3000
或http://your_server_ip:3000
的默认视图将是默认值Rails 欢迎页面。要将应用程序的根视图映射到 sharks 控制器的
index
视图,通过删除#
取消注释默认的#root articles#index
并将article
替换为shark
:Rails.application.routes.draw do resources :sharks root 'sharks#index' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
完成编辑后保存文件并退出编辑器。如果您使用
nano
退出文件,请按CTRL+X
、Y
,然后按ENTER
现在,当用户导航到您的应用程序根目录时,他们会进入 shark 登陆页面,而不是默认的 Rails 登陆页面。此外,他们现在有机会创建新的鲨鱼条目、查看现有条目以及编辑或删除给定的条目。
接下来,使用以下命令运行迁移:
- rails db:migrate
此输出确认迁移:
Output== 20230124215633 CreateSharks: migrating ===================================== -- create_table(:sharks) -> 0.0041s == 20230124215633 CreateSharks: migrated (0.0045s) ============================再次启动 Rails 服务器。如果您在本地工作,请运行:
- rails s
在开发服务器上,运行:
- rails s --binding=your_server_ip
如果您在本地工作,请导航至
localhost:3000
,如果您在开发服务器上工作,请导航至http://your_server_ip:3000
,以访问您的新登陆页面:要创建新的鲨鱼,请单击“新建鲨鱼”链接。此链接会将您带到
sharks/new
路线:您可以添加一些信息来测试您的应用程序。在“名称”字段中写入“Great White”,在“事实”字段中写入“Scary”:
然后,按创建鲨鱼按钮创建鲨鱼。
此按钮会将您定向到
show
路由,感谢before_action
过滤器,该路由是使用set_shark
方法设置的,该方法获取id
:class SharksController < ApplicationController before_action :set_shark, only: %i[ show edit update destroy ] . . . # GET /sharks/1 or /sharks/1.json def show end . . . private # Use callbacks to share common setup or constraints between actions. def set_shark @shark = Shark.find(params[:id]) end . . .
您可以通过在 shark 条目上按 Edit this shark 来测试编辑功能。这会将您带到该鲨鱼的
edit
路线:将关于大白鲨的
facts
更新为 \Large 而不是 \Scary,然后按 Update Shark。这将带您回到show
路线:最后,按 Back to sharks 会将您带到更新后的
index
视图:现在您已经测试了应用程序的基本功能,您可以添加一些验证和安全检查来使一切更加安全。
第 5 步 — 添加验证
您的 shark 应用程序可以接受来自用户的输入,但想象一下这样一种情况:用户试图在不向其添加事实的情况下创建一条 shark,或者为数据库中已有的 shark 创建一个条目。您可以通过向模型添加验证来创建在数据输入数据库之前检查数据的机制。由于您的应用程序的逻辑位于其模型中,因此在那里验证数据输入是合适的。
请注意,本教程不包括编写验证测试,但您可以通过查阅 Rails 文档了解有关测试的更多信息。
如果您还没有停止服务器,请立即在终端中按
CTRL+C
停止服务器。打开您的
shark.rb
模型文件:- nano app/models/shark.rb
目前,该文件告诉我们
Shark
类继承自ApplicationRecord
,后者又继承自ActiveRecord::Base
:class Shark < ApplicationRecord end
向
name
字段添加一些验证以确认该字段已填写并且条目是唯一的,以防止重复条目:class Shark < ApplicationRecord validates :name, presence: true, uniqueness: true end
接下来,为
facts
字段添加验证以确保它也已填写:class Shark < ApplicationRecord validates :name, presence: true, uniqueness: true validates :facts, presence: true end
validates: facts, presence: true
代码行不关心事实的唯一性。它验证了它与独特的鲨鱼条目的关联。完成后保存并关闭文件。
使用
rails s
或rails s --binding=your_server_ip
再次启动您的服务器,然后导航到位于的应用程序根目录http://localhost:3000
或http://your_server_ip:3000
。按新鲨鱼链接。在表单中,将 \Great White 添加到名称字段,将 \Big Teeth 添加到 Facts 字段,然后按创建鲨鱼。在这种情况下会出现一条警告消息:
要检查其他验证,请单击 Back to sharks 返回主页,然后再次按 New Shark。在新表单中,在名称字段中输入“Tiger Shark”,并将 Facts 留空。当您按 Create Shark 时,它会输出以下警告:
通过这些更改,您的应用程序进行了一些验证,以确保保存到数据库的数据的一致性。现在您可以将注意力转向应用程序的用户并定义谁可以修改应用程序数据。
第 6 步 — 添加身份验证
通过一些验证,您对保存到数据库的数据有一些保证。但是用户呢?如果您不希望任何和所有用户添加到数据库中,那么您应该添加一些身份验证措施以确保只有允许的用户才能添加鲨鱼。为此,请使用
http_basic_authenticate_with
方法,该方法允许创建用户名和密码组合来验证用户。有多种方法可以使用 Rails 对用户进行身份验证,包括使用
devise
gem。但是,现在,向您的应用程序控制器添加一个方法,该方法将应用于整个应用程序的操作。如果您将来向应用程序添加更多控制器,这将很有用。使用
CTRL+C
停止您的服务器。打开定义您的
ApplicationController
的文件:- nano app/controllers/application_controller.rb
里面是
ApplicationController
类的定义,应用程序中的其他控制器继承自该类:class ApplicationController < ActionController::Base end
要对用户进行身份验证,请使用带有
http_basic_authenticate_with
方法的硬编码用户名和密码。将以下代码添加到文件中:class ApplicationController < ActionController::Base http_basic_authenticate_with name: 'sammy', password: 'shark', except: [:index, :show] end
除了在此处提供用户名和密码外,您还通过指定不需要的路由来限制身份验证:
index
和show
。实现此目的的另一种方法是仅编写:[:create, :update, :destroy]
。这样,所有用户都将能够访问所有鲨鱼并阅读有关特定鲨鱼的信息。然而,当谈到修改网站内容时,用户需要证明他们有访问权限。在更健壮的设置中,您不希望以这种方式对值进行硬编码,但此示例演示了如何为应用程序的路由包含身份验证。 Rails 默认将会话数据存储在 cookie 中:一旦您对指定操作进行身份验证,就不需要在同一会话中再次进行身份验证。
完成编辑后保存并关闭
app/controllers/application_controller.rb
。您现在可以实际测试身份验证。使用
rails s
或rails s --binding=your_server_ip
启动服务器并通过http:// 导航到您的应用程序localhost:3000
或http://your_server_ip:3000
。在着陆页上,按下 New Shark 按钮。这将触发以下身份验证窗口:
如果您输入用户名
sammy
和密码shark
,这是您添加到app/controllers/application_controller.rb
的组合,您将能够安全地创造出一条新的鲨鱼。您现在有一个工作的 shark 应用程序,完成了数据验证和基本的身份验证方案。
结论
您在本教程中创建的 Rails 应用程序是您可以用于进一步开发的起点。如果您有兴趣探索 Rails 生态系统,项目文档是一个很好的起点。
您还可以通过阅读如何为 Ruby on Rails 应用程序创建嵌套资源来了解有关向项目添加嵌套资源的更多信息,它将向您展示如何构建应用程序的模型和路由。
此外,您可能想探索如何使用框架为您的项目设置更强大的前端,例如如何使用 React 前端设置 Ruby on Rails 项目提供了有关如何执行此操作的指导。
如果您想探索不同的数据库选项,您还可以查看 PostgreSQL 教程以了解有关使用此数据库的更多信息。