接Rails3入门(5)
1. 重构
现在, 我们博客的文章和评论都可以工作了, 但是如果我们看下 app/views/posts/show.html.erb 模板, 你会发现其代码又长又笨, 还记得Rails的信条么? DRY!(不要做重复的事, Dont Repeat Yourself)
现在我们使用局部模板来清理下这些代码吧.
首先我们制作一个comment模板来显示一条文章下的所有评论. 创建 app/views/comments/_comment.erb :
<p>
<b>Commenter:</b>
<%= comment.commenter %>
</p>
<p>
<b>Comment:</b>
<%= comment.body %>
</p>
然后修改 posts下面的show.html.erb模板:
<p class="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>
<%= render @post.comments %>
<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 %> |
这将为每条评论渲染 app/views/comments/下面的_comment.erb局部模板, 因为传入 render 方法的参数是一个集合 (<%= render @post.comments %>), rails会自动判断参数是否是集合, 如果是, 将遍历集合同时输出局部模板 (在这里, _comment.erb局部模板的变量名称为 comment, 然后comments集合的每个元素分配给该comment变量)
请想想 form_for [@post, @post.comments.build] 方法生成表单的action为: posts/:id/comment, 那么对于REST路由, 我们在后面将会深入了解.
同样, 我们把创建评论部分也移到局部模板中去, 创建文件 app/views/comments/_form.erb:
<%= form_for([@post, @post.comments.build]) do |f| %>
<div class="field">
<%= f.label :commenter %>
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :body %>
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
最后的show.html.erb为这个样子:
<p class="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>
<%= render @post.comments %>
<h2>Add a comment:</h2>
<%= render "comments/form" %>
<br />
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
第二个局部模板就比较简单了, 没有变量的赋值, 仅仅引用了comments下的_form.erb模板, 通过"/", rails知道你渲染的是comments文件夹下的_form模板.
再次说明一点的是: @post 作用于任何该视图下的局部模板, 因为它是一个实例变量.
2. 删除评论
博客中另一个重要特性是可以删除垃圾评论, 要实现该功能, 我们需要在每条评论下建立一个链接, 并实现CommentController下面的destroy动作.
所以首先, 我们先在_comment.erb模板下添加一条删除链接:
<p>
<b>Commenter:</b>
<%= comment.commenter %>
</p>
<p>
<b>Comment:</b>
<%= comment.body %>
</p>
<p>
<%= link_to 'Destroy Comment', [comment.post, comment],
:confirm => 'Are you sure?',
:method => :delete %>
</p>
同样也请留意下 link_to 生成的url: posts/:id/comments/:id, 以及产生一个delete请求(注意不是get, 想想如果可以通过get来删除数据是不是很糟糕? 一般来说对于查询数据我们使用get请求, 对于操作数据使用post请求, 所以对于一个搜索功能来说, 即使是表单提交, 那么我们也应该把表单的method设为get)
接下来我们实现CommentsController下的destroy方法(怎么会调用该方法? 记住这是一个REST)
def destroy
@post = Post.find(params[:post_id])
@comment = @post.comments.find(params[:id])
@comment.destroy
redirect_to(post_path(@post))
end
destroy方法首先找到该篇文章, 然后在@post.comments集合内锁定需要删除的评论, 删除之后跳转到该文章地址.
3. 删除关联对象
如果你删除一篇文章, 那么相关的评论也一并删除. 否则评论还将继续留在数据库中占用空间. Rails同样允许你使用依赖选项来激活. 修改Post模型:
class Post < ActiveRecord::Base
validates :name, :presence => true
validates :title, :presence => true,
:length => { :minimum => 5 }
has_many :comments, :dependent => :destroy
end
:dependent => :destroy 告诉rails当删除一条post时, 相关的comments将调用destroy方法一并删除, 如果设置为 :delete_all 那么关联对象将被删除而不调用它们的 destroy 方法, 如果设置为 :nullify, 所有关联对象的外键将被设为 null 而不调用他们的 save 回调; 如果设置为 :restrict 那么该对象在有关联对象存在的时候无法被删除. (注意一点的是 :dependent 在使用 :through 选项时将被忽略)
4. 安全
现在我们要发布博客里, 可以我们发现所有人都可以添加 删除 修改文章和评论.
那么rails提供了一个非常简单的HTTP认证, 那么我们需要在全局控制器内实现它:
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
private
def authenticate
authenticate_or_request_with_http_basic do |user_name, password|
user_name == 'admin' && password == 'password'
end
end
end
然后我们需要在PostsController阻止未认证用户的一些动作的访问, 那么在这里我们可以使用 before_filter 过滤器. 该方法将在每个动作执行前运行, 除非一些通过 :except 设置的方法:
class PostsController < ApplicationController
before_filter :authenticate, :except => [:index, :show]
...
end
同样的, 我们只允许认证用户可以删除评论:
class CommentsController < ApplicationController
before_filter :authenticate, :only => :destroy
...
end
现在如果你创建post, 你将被要求输入用户名和密码.
Good Luck!
分享到:
相关推荐
《Rails入门教程一》是针对初学者的一份详尽指南,旨在帮助读者快速掌握Ruby on Rails框架的基础知识。Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式...
《Rails 101 入门电子书》是一本非常适合初学者直接入门的书籍,它由xdite编写并出版于2014年6月10日。本书主要针对的是希望学习Ruby on Rails框架的读者,特别是那些想要从零开始掌握这项技术的新手。 #### 二、...
在"Ruby on Rails入门例子"中,我们可能会遇到以下关键概念: - **路由(Routes)**:Rails的路由系统将URL映射到特定的控制器动作,定义了应用的导航结构。在`config/routes.rb`文件中配置路由规则。 - **生成器...
本压缩包中的"Ruby on Rails入门经典代码"提供了新手学习Rails的宝贵资源,帮助初学者快速掌握这个强大的框架。 1. **Rails基础知识**: - MVC架构:Rails的核心设计模式,模型负责数据处理,视图负责展示,控制器...
在Ruby on Rails入门经典中,你将学习到以下核心知识点: 1. **Ruby语言基础**:首先,你需要了解Ruby的基础语法,包括变量、数据类型(如字符串、整数、浮点数、数组、哈希)、控制结构(如条件语句if/else,循环...
[Apress] Rails 3 入门教程 (英文版) [Apress] Beginning Rails 3 (E-Book) ☆ 出版信息:☆ [作者信息] Cloves Carneiro Jr., Rida Al Barazi [出版机构] Apress [出版日期] 2010年09月01日 [图书页数] 400页...
总的来说,《Ruby on Rails入门权威经典》是一本内容丰富、实践性强的教程,它不仅教授了Ruby on Rails的基础知识,还提供了许多实用技巧和最佳实践,是初学者入门Rails的理想选择。通过阅读本书,读者不仅能学会...
通过《Ruby on Rails 入门经典教程》,无论你是编程新手还是希望转行Web开发的计算机操作者,都可以系统地掌握Ruby on Rails的核心知识,开启Web开发之旅。aybook.cn_rinumzwb1227.pdf这份文档正是这个宝贵资源的...
ruby on rails文档,rails3入门指南
Ruby on Rails:Rails框架入门.docx
- **《Ruby on Rails 3 教程》**:由Michael Hartl编写的一本经典教材,被广泛认为是学习Rails的最佳资源之一。 - **教学方法**: - **示例驱动**:通过具体的项目示例来讲解Rails的各种功能。 - **循序渐进**:从...
以上是Ruby on Rails入门的基础知识,通过学习这些,你可以开始构建自己的Web应用。对于初学者,建议跟随一个详细的教程逐步实践,结合实际案例理解Rails的工作原理。在学习过程中,不断练习和调试代码,加深对框架...