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 :commentsend
上面的代码在 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内容请搜索靠谱客的其他文章。
发表评论 取消回复