概述
rails new 项目名字 创建新项目
bin/rails server 启动服务器
bin/rails generate controller Welcome index 生成控制器和视图和一个路由
app/views/welcome/index.html.erb
在此替换html内容
在跟路由config/routes.rb 添加root 'welcome#index'
配置路由信息,更换路由路径
在 Blog 应用中创建一个资源(resource)。资源是一个术语,表示一系列类似对象的集合,如文章、人或动物。资源中的项目可以被创建、读取、更新和删除,这些操作简称 CRUD(Create, Read, Update, Delete)。
Rails 提供了 resources
方法,用于声明标准的 REST 资源
# 添加资源 添加后会生成很多资源路由。resources :articles
注意!资源添加后,路由没有对应的控制器,需要执行bin/rails generate controller Articles,并手动定义动作,只需要定义一个新方法就可以生成对应的控制器!!!
控制器实际上只是一个继承自 ApplicationController
的类,执行 CRUD 操作,在 Ruby 中,有 public
、private
和 protected
三种方法,其中只有 public
方法才能作为控制器的动作。
ps: 执行 bin/rails routes
命令,可以看到所有标准 REST 动作都具有对应的路由。
第一个页面
当浏览器点击访问时,request.formats访问格式默认是text/html,因此 Rails 会查找 HTML 模板,request.variant
指明伺服的是何种物理设备,帮助 Rails 判断该使用哪个模板渲染响应。它的值是空的,因为没有为其提供信息。
提醒:模板的格式只能是 html
,模板处理器只能是 erb
、builder
和 coffee
中的一个。:erb
是最常用的 HTML 模板处理器,:builder
是 XML 模板处理器,:coffee
模板处理器用 CoffeeScript 创建 JavaScript 模板。因为我们要创建 HTML 表单,所以应该使用能够在 HTML 中嵌入 Ruby 的 ERB
语言。
所以需要创建 articles/new.html.erb
文件,并把它放在应用的 app/views
文件夹中。
创建好了,就可以把改html视图在浏览器上渲染出来了。
第一个表单
Rails 中最常用的表单构建器是 form_for
辅助方法
调用 form_for
辅助方法时,需要为表单传递一个标识对象作为参数,这里是 :article
符号。这个符号告诉 form_for
辅助方法表单用于处理哪个对象。在 form_for
辅助方法的块中,f
表示 FormBuilder
对象,用于创建两个标签和两个文本字段,分别用于添加文章的标题和正文。最后在 f
对象上调用 submit
方法来为表单创建提交按钮。
存在一点:表单 action
属性的值是 /articles/new
,指向的是当前页面。
应该把表单指向其他 URL,为此可以使用 form_for
辅助方法的 :url
选项。在 Rails 中习惯用 create
动作来处理提交的表单,因此应该把表单指向这个动作。
修改 app/views/articles/new.html.erb
文件的 form_for
这一行,改为:
|
articles_path
辅助方法传递给 :url
选项,articles_path
辅助方法告诉 Rails 把表单指向和 articles
前缀相关联的 URI 模式。默认情况下,表单会向这个路由发起 POST
请求。这个路由和当前控制器 ArticlesController
的 create
动作相关联。
创建完后,在到对应的控制器添加create动作,表单就ok了~~ 表单提交后,其字段以参数形式传递给 Rails,然后就可以在控制器动作中引用这些参数,以执行特定任务。
|
这里 render
方法接受了一个简单的散列(hash)作为参数,:plain
键的值是 params[:article].inspect
。params
方法是代表表单提交的参数(或字段)的对象。params
方法返回 ActionController::Parameters
对象,这个对象允许使用字符串或符号访问散列的键。这里我们只关注通过表单提交的参数。
请确保牢固掌握 params
方法,这个方法很常用。让我们看一个示例 URL:http://www.example.com/?username=dhh&email=dhh@email.com
。在这个 URL 中,params[:username]
的值是“dhh”,params[:email]
的值是“dhh@email.com
”。
创建模型:bin/rails generate model Article title:string text:text
执行迁移命令,生成迁移模型表:bin/rails db:migrate 该模型表默认在开发环境生成表,要想在其他环境中执行迁移,例如生产环境,就必须在调用命令时显式传递环境变量:bin/rails db:migrate RAILS_ENV=production
。
生成模型后可以去保存,调用create动作,如:
|
为控制器参数设置白名单,以避免错误地批量赋值。:@article
= Article.
new
(params.require(
:article
).permit(
:title
,
:text
))
另外,除了批量赋值问题,为了禁止从外部调用这个方法,通常还要把它设置为 private
。
|
动作提醒:标准的 CRUD 动作:index
,show
,new
,edit
,create
,update
和 destroy
。你也可以按照自己的顺序放置这些动作,但要记住它们都是公开方法,如前文所述,必须放在私有方法之前才能正常工作。
|
Article.find
来查找文章,并传入 params[:id]
以便从请求中获得 :id
参数。我们还使用实例变量(前缀为 @
)保存对文章对象的引用。
在视图函数里:
|
对应的实例属性.属性值可以将之前的属性用上。
所有表单页面视图/默认设置为首页
添加动作
def
index
@articles
= Article.all
end
添加视图html/index.html
添加链接
<%=
link_to
'My Blog'
, controller:
'articles'
%>
|
<%=
link_to
'Back'
, articles_path
%>
以上方法都包含对各个视图的链接,利用该超链接将视图关系建立。
添加验证
目前模型文件简单到只有两行代码,ApplicationRecord
类继承自 ActiveRecord::Base
类。正是 ActiveRecord::Base
类为 Rails 模型提供了大量功能,包括基本的数据库 CRUD 操作(创建、读取、更新、删除)、数据验证,以及对复杂搜索的支持和关联多个模型的能力。
validates
:title
, presence:
true
,
length: { minimum:
5
}
添加的代码用于确保每篇文章都有标题,并且标题长度不少于 5 个字符。在 Rails 模型中可以验证多种条件,包括字段是否存在、字段是否唯一、字段的格式、关联对象是否存在,等等。
此时应该调整视图逻辑,当用户文章条件满足及不满足都要返回相应的视图:
|
if
@article
.save
redirect_to
@article
else
render
'new'
在 new
动作中创建了新的实例变量 @article
,在 create
动作中,当 save
返回 false
时,我们用 render
代替了 redirect_to
。使用 render
方法是为了把 @article
对象回传给 new
模板。这里渲染操作是在提交表单的这个请求中完成的,而 redirect_to
会告诉浏览器发起另一个请求。
修改完逻辑后,还要修改对应的视图页面(添加显示错误信息的代码:):
<%
if
@article
.errors.any?
%>
<
div
id
=
"error_explanation"
>
<
h2
>
<%=
pluralize(
@article
.errors.count,
"error"
)
%>
prohibited
this article from being saved:
</
h2
>
<
ul
>
<%
@article
.errors.full_messages.
each
do
|msg|
%>
<
li
>
<%=
msg
%>
</
li
>
<%
end
%>
</
ul
>
</
div
>
<%
end
%>
我们使用 @article.errors.any?
检查是否有错误,如果有错误就使用 @article.errors.full_messages
列出所有错误信息。
pluralize
是 Rails 提供的辅助方法,接受一个数字和一个字符串作为参数。如果数字比 1 大,字符串会被自动转换为复数形式。
在 ArticlesController
的new动作中添加 @article = Article.new
是因为如果不这样做,在视图中 @article
的值就会是 nil
,这样在调用 @article.errors.any?
时就会抛出错误。
更新文章
在 ArticlesController
中添加 edit
动作,通常把这个动作放在 new
动作和 create
动作之间,接下来在视图中添加一个表单,这个表单类似于前文用于新建文章的表单。创建 app/views/articles/edit.html.erb
文件
method: :patch
选项告诉 Rails 使用 PATCH
方法提交表单。根据 REST 协议,PATCH
方法是更新资源时使用的 HTTP 方法。
接下来在 app/controllers/articles_controller.rb
文件中创建 update
动作
另外不用把所有属性都传递给 update
方法。例如,调用 @article.update(title: 'A new title')
时,Rails 只更新 title
属性而不修改其他属性。
最后,我们想在文章列表中显示指向 edit
动作的链接,接着在 app/views/articles/show.html.erb
模板中添加 Edit
链接,这样文章页面也有 Edit
链接了。
使用局部视图去掉视图中的重复代码
按照约定,局部视图的文件名以下划线开头。除了第一行 form_for
的用法变了之外,其他代码都和之前一样。之所以能用这个更短、更简单的 form_for
声明来代替新建文章页面和编辑文章页面的两个表单,是因为 @article
是一个资源,对应于一套 REST 式路由,Rails 能够推断出应该使用哪个地址和方法。更新 相关视图,以使用新建的局部视图。把文件内容替换。
删除文章
删除资源的路由应该使用 delete
路由方法。如果在删除资源时仍然使用 get
路由,就可能给那些设计恶意地址的人提供可乘之机:
delete
方法来删除资源,对应的路由会映射到 app/controllers/articles_controller.rb
文件中的 destroy
动作。
destroy
动作是控制器中的最后一个 CRUD 动作,和其他公共 CRUD 动作一样,这个动作应该放在 private
或 protected
方法之前。
注意,我们不需要为 destroy
动作添加视图,因为完成操作后它会重定向到 index
动作。
最后,在 index
动作的模板(app/views/articles/index.html.erb
)中加上“Destroy”链接,这样就大功告成了:
link_to
辅助方法生成“Destroy”链接的用法有点不同,其中第二个参数是具名路由(named route),还有一些选项作为其他参数。method: :delete
和 data: { confirm: 'Are you sure?' }
选项用于设置链接的 HTML5 属性,这样点击链接后 Rails 会先向用户显示一个确认对话框,然后用 delete
方法发起请求。这些操作是通过 JavaScript 脚本 rails-ujs
实现的,这个脚本在生成应用骨架时已经被自动包含在了应用的布局中(app/views/layouts/application.html.erb
)。如果没有这个脚本,确认对话框就无法显示。
添加第二个模型(用于处理文章评论)
生成模型 bin/rails generate model Comment commenter:string body:text article:references
references
关键字是一种特殊的模型数据类型,用于在数据表中新建字段。这个字段以提供的模型名加上 _id
后缀作为字段名,保存整数值。
上面的命令会生成 4 个文件:
文件 | 用途 |
---|---|
db/migrate/20140120201010_create_comments.rb | 用于在数据库中创建 comments 表的迁移文件(你的文件名会包含不同的时间戳) |
app/models/comment.rb | Comment 模型文件 |
test/models/comment_test.rb | Comment 模型的测试文件 |
test/fixtures/comments.yml | 用于测试的示例评论 |
belongs_to
:article
这行代码用于建立 Active Record 关联。声明每一条评论都属于某一篇文章,模型关联的另一端:article.rb,添加has_many
:comments.
例如,如果 @article
实例变量表示一篇文章,就可以使用 @article.comments
以数组形式取回这篇文章的所有评论。
t.references
这行代码创建 article_id
整数字段,为这个字段建立索引,并建立指向 articles
表的 id
字段的外键约束。
数据库生成表命令:bin/rails db:migrate
为评论添加路由
resources
:articles
do
resources
:comments
end
上面的代码在 articles
资源中创建 comments
资源,这种方式被称为嵌套资源。这是表明文章和评论之间层级关系的另一种方式。
生成控制器
bin/rails generate controller Comments
上面的命令会创建 5 个文件和一个空文件夹:
文件/文件夹 | 用途 |
---|---|
app/controllers/comments_controller.rb | Comments 控制器文件 |
app/views/comments/ | 控制器的视图保存在这里 |
test/controllers/comments_controller_test.rb | 控制器的测试文件 |
app/helpers/comments_helper.rb | 视图辅助方法文件 |
app/assets/javascripts/comments.coffee | 控制器的 CoffeeScript 文件 |
app/assets/stylesheets/comments.scss | 控制器的样式表文件 |
修改显示文章的模板(app/views/articles/show.html.erb
),添加发表评论的功能
<
h2
>Add a comment:</
h2
>
<%=
form_for([
@article
,
@article
.comments.build])
do
|f|
%>
<
p
>
<%=
f.label
:commenter
%>
<
br
>
<%=
f.text_field
:commenter
%>
</
p
>
<
p
>
<%=
f.label
:body
%>
<
br
>
<%=
f.text_area
:body
%>
</
p
>
<
p
>
<%=
f.submit
%>
</
p
>
<%
end
%>
调用 CommentsController
的 create
动作来发表评论。这里 form_for
辅助方法以数组为参数,会创建嵌套路由,例如 /articles/1/comments
。
接下来在 app/controllers/comments_controller.rb
文件中添加 create
动作:
|
上面的代码比 Articles
控制器的代码复杂得多,这是嵌套带来的副作用。对于每一个发表评论的请求,都必须记录这条评论属于哪篇文章,因此需要在 Article
模型上调用 find
方法来获取文章对象。
此外,上面的代码还利用了关联特有的方法,在 @article.comments
上调用 create
方法来创建和保存评论,同时自动把评论和对应的文章关联起来。
添加评论后,我们使用 article_path(@article)
辅助方法把用户带回原来的文章页面。如前文所述,这里调用了 ArticlesController
的 show
动作来渲染 show.html.erb
模板,因此需要修改 app/views/articles/show.html.erb
文件来显示评论:
渲染局部视图集合
创建评论的局部视图,把显示文章评论的代码抽出来
|
修改 app/views/articles/show.html.erb
,这样对于 @article.comments
集合中的每条评论,都会渲染 app/views/comments/_comment.html.erb
文件中的局部视图。render
方法会遍历 @article.comments
集合,把每条评论赋值给局部视图中的同名局部变量,也就是这里的 comment
变量。
渲染局部视图表单
把添加评论的代码也移到局部视图中。创建 app/views/comments/_form.html.erb
文件,添加下面的代码
|
修改 app/views/articles/show.html.erb
文件
上面的代码中第二个 render
方法的参数就是我们刚刚定义的 comments/form
局部视图。Rails 很智能,能够发现字符串中的斜线,并意识到我们想渲染 app/views/comments
文件夹中的 _form.html.erb
文件。
@article
是实例变量,因此在所有局部视图中都可以使用。
删除评论
在视图中添加一个链接,并在 CommentsController
中添加 destroy
动作。
点击“Destroy Comment”链接后,会向 CommentsController
发起 DELETE /articles/:article_id/comments/:id
请求,这个请求将用于删除指定评论。下面在控制器(app/controllers/comments_controller.rb
)中添加 destroy
动作:
destroy
动作首先找到指定文章,然后在 @article.comments
集合中找到指定评论,接着从数据库删除这条评论,最后重定向到显示文章的页面。
删除关联对象
如果要删除一篇文章,文章的相关评论也需要删除,否则这些评论还会占用数据库空间。在 Rails 中可以使用关联的 dependent
选项来完成这一工作。像下面这样修改 app/models/article.rb
文件中的 Article
模型:
|
如果要删除一篇文章,文章的相关评论也需要删除,否则这些评论还会占用数据库空间。在 Rails 中可以使用关联的 dependent
选项来完成这一工作。像下面这样修改 app/models/article.rb
文件中的 Article
模型:
|
安全
我们需要一种方法来禁止未认证用户访问 ArticlesController
的动作。这里我们可以使用 Rails 的 http_basic_authenticate_with
方法,通过这个方法的认证后才能访问所请求的动作。
要使用这个身份验证系统,可以在 app/controllers/articles_controller
文件中的 ArticlesController
的顶部进行指定。这里除了 index
和 show
动作,其他动作都要通过身份验证才能访问,为此要像下面这样添加代码:
|
同时只有通过身份验证的用户才能删除评论,为此要在 CommentsController
(app/controllers/comments_controller.rb
)中像下面这样添加代码:
|
最后
以上就是小巧水池为你收集整理的ruby on rails 项目体验的全部内容,希望文章能够帮你解决ruby on rails 项目体验所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复