ruby on rails入门教程之post构建六

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

那么从前面的教程中我们学习了如何创建一个简单的博客应用, 我个人觉得无论你是新手还是从rails2 过来, rails3 还是比较容易上手的, 现在我们就来看下rails3 相比rails2, 进步在哪里, 优势又在什么地方. ( 本来这章打算写ujs, 无奈工作繁忙只能推到周日了)

1. 脚本命令

旧的命令                                      新的用法

script/generate                          rails g

script/console                            rails c

script/server                              rails s

script/dbconsole                        rails db

2. 配置文件

rails2: config/environment.rb

  1. Rails::Initializer.run  do  |config|  

  2.     config.load_paths += %W( #{RAILS_ROOT}/extras )   

  3.     config.gem "bj"   

  4.     config.gem "sqlite3-ruby" ,  :lib  =>  "sqlite3"   

  5.     config.gem "aws-s3" ,  :lib  =>  "aws/s3"   

  6.     config.plugins = [ :exception_notification  ]  

  7.     config.time_zone = 'UTC'   

  8. end   

rails3:config/application.rb

  1. module  APP_NAME  

  2.     class  Application < Rails::Application  

  3.         config.load_paths += %W( #{RAILS_ROOT}/extras )   

  4.         config.plugins = [ :exception_notification  ]  

  5.         config.time_zone = 'UTC'   

  6.     end   

  7. end   

这样就变成了一种架构式的应用, 我们可以根据方便的对config 进行操作

3. 路由

rails3, 已经的路由可以继续工作, 而新的路由方式更加简洁.

rails2 :

  1. map.resources  :posts   do  |post|  

  2.     post.resources :comments   

  3. end   

而在rails3, 表达更为形象:

  1. resources  :posts   do   

  2.     resources :comments   

  3. end   

对于一些复杂的路由, rails2:

  1. post.resources  :comments ,  

  2.                  :member  => {  :preview  =>  :post  },  

  3.                  :collection  => {  :archived  =>  :get  }  

rails3 中可以这样表达:

  1. resources  :comments   do   

  2.     member do   

  3.         post :preview   

  4.     end   

  5.     collection do   

  6.         get :archived   

  7.     end   

  8. end   

不够简洁? 我们还可以这样做:

  1. resources  :comments   do   

  2.     post :preview ,  :on  =>  :member   

  3.     get :archived ,  :on  =>  :collection   

  4. end   

对于基本路由, rails2:

  1. map.connect  'login' ,  :controller  =>  'session' ,  :action  =>  'new'   

那么在rails3:

  1. match  'login'  =>  'session#new'   

对于具名路由, rails2:

  1. map.login  'login' ,  :controller  =>  'session' ,  :action  =>  'new'   

rails3:

 

  1. match  'login'  =>  'session#new' ,  :as  =>  :login   

对于程序根路由, rails2:

  1. map.root :controller =>  'users' , :action =>  'index'   

rails3:

  1. root  :to  =>  'users#index'   

对于遗留路由, rails2:

  1. map.connect  ':controller/:action/:id'   

  2. map.connect ':controller/:action/:id.:format'   

那么在rails3 中写法更优雅:

  1. match  ':controller(/:action(/:id(.:format)))'   

对于路由参数, rals2:

  1. map.connect  '/articles/:year/:month/:day' ,  :controller  =>  'posts' ,  :action  =>  'index'   

rails3:

  1. match  '/articles/:year/:month/:day'  =>  "posts#index"   

那么对于存档请求, 比如rails2:

  1. map.connect  '/articles/:year/:month/:day' ,  :controller  =>  'posts' ,  :action  =>  'index'   

  2. map.connect '/articles/:year/:month' ,  :controller  =>  'posts' ,  :action  =>  'index'   

  3. map.connect '/articles/:year' ,  :controller  =>  'posts' ,  :action  =>  'index'   

rails3:

  1. match  '/articles(/:year(/:month(/:day)))'  =>  "posts#index"   

指定请求方式, rails2:

 

  1. map.connect  '/articles/:year' ,  :controller  =>  'posts' ,  :action  =>  'index' ,  

  2. :conditions  => { :method  =>  :get }  

rails3:

  1. match  '/articles/:year'  =>  "posts#index" ,  :via  =>  :get   

  2. # 或者更简单的:   

  3. get '/articles/:year'  =>  "posts#index"   

对于跳转, rails3:

  1. match  'signin' ,  :to  => redirect( "/login" )  

  2. match 'users/:name' ,  :to  => redirect {|params|  "/#{params[:name]}"  }  

  3. match 'google'  => redirect( 'http://www.google.com/' )  

路由约束: rails2 中实际上使用了 :requirements 符号

  1. map.connect  '/:year' ,  :controller  =>  'posts' ,  :action  =>  'index' ,  

  2.                                     :requirements  => {  :year  => /\d{4}/ }  

rails3:

  1. match  '/:year'  =>  "posts#index" ,  :constraints  => { :year  => /\d{4}/}  

  1. :constraints  => {  :user_agent  => /iphone/ }  

  2. :constraints  => {  :ip  => /192\.168\.1\.\d{1,3}/ }  

  3. constraints(:host  => /localhost/)  do   

  4.     resources :posts   

  5. end   

  6. constraints IpRestrictor do   

  7.     get 'admin/accounts'  =>  "queenbee#accounts"   

  8. end   

对于Rack 应用, rails3:

  1. get  'hello'  => proc { |env| [200, {},  "Hello Rack" ] }  

  2.  

  3. get 'rack_endpoint'  => PostsController.action( :index )  

  4.  

  5. get 'rack_app'  => CustomRackApp  

4. Bundler ActionController

一个典型的rails 应用, 我们一般需要在 environment.rb 指定你的 gems:

  1. config.gem  "haml"   

  2. config.gem "chronic" ,  :version  =>  '0.2.3'   

然后我们运行 $ rake gems:install, 该命令会取得并下载然后安装编译这些gems 到你的系统RubyGems 目录中.

之后我们运行 $ rake gems:unpack:dependencise, 把这些gem 打包到你应用程序的vendor/gems 目录中去.

这样做产生的问题:

1. 它直接绑定到Rails

2. 没有从本质上解决依赖问题

3. 运行时容易发生冲突

rails3, 使用了 bundle 命令:

直接在你的 gemfile 中指定你的 gem

  1. gem  "haml"   

  2. gem "chronic" ,  '0.2.3'   

然后运行 $ bundle, 该命令会会取得并下载然后安装编译这些gems

然后运行 $ bundle package gem 源移到/vendor/cache 中去.

这样rails 应用中的gem 与系统中的gem 就不会相冲突.

一般的控制器语法:

  1. class  UsersController < ApplicationController  

  2.     def  index  

  3.         @users  = User.all  

  4.         respond_to do  |format|  

  5.             format.html  

  6.             format.xml { render :xml  =>  @users .to_xml }   

  7.         end   

  8.     end   

  9.  

  10.     def  show  

  11.         @user  = User.find(params[ :id ])  

  12.         respond_to do  |format|  

  13.             format.html # show.html.erb   

  14.             format.xml { render :xml  =>  @user  }  

  15.         end   

  16.     end   

  17.  

  18. ...  

改进的语法:

  1. class  UsersController < ApplicationController  

  2.     respond_to :html ,  :xml ,  :json   

  3.     def  index  

  4.         @users  = User.all  

  5.         respond_with(@users )  

  6.     end   

  7.     def  show  

  8.         @user  = User.find(params[ :id ])  

  9.         respond_with(@user )  

  10.     end   

  11. ...  

5. ActionMailer

rails2:  $ script/generate mailer UserMailer welcome forgot_password

这将创建 app/models/user_mailer.rb

那么在rails3: $ rails g mailer UserMailer welcome forgot_password

这将创建 app/mailers /user_mailer.rb

在实现部分, rails2:

  1. def  welcome(user, subdomain)  

  2.     subject 'Welcome to TestApp'   

  3.     recipients user.email  

  4.     from 'admin@testapp.com'   

  5.     body :user  => user,  :subdomain  => subdomain  

  6. end   

  1. UserMailer.deliver_welcome(user, subdomain)   

rails3:

  1. def  welcome(user, subdomain)  

  2.     @user  = user  

  3.     @subdomain  = subdomain  

  4.     mail(:from  =>  "admin@testapp.com" ,  

  5.             :to  => user.email,  

  6.             :subject  =>  "Welcome to TestApp" )  

  7. end   

  1. UserMailer.welcome(user, subdomain).deliver  

相比rails2, 我们在rails3 下实现一个mail 要简单的多:

  1. class  UserMailer < ActionMailer::Base  

  2.     default :from  =>  "admin@testapp.com" ,  

  3.                 :reply_to  =>  "noreply@testapp.com" ,  

  4.                 "X-Time-Code"  =>  Time .now.to_i.to_s  

  5.     def  welcome(user, subdomain)  

  6.         @user  = user  

  7.         @subdomain  = subdomain  

  8.         attachments['test.pdf' ] =  File .read( "#{Rails.root}/public/test.pdf" )  

  9.         mail(:to  =>  @user .email,  :subject  =>  "Welcome to TestApp" )  do  |format|  

  10.             format.html { render 'other_html_welcome'  }  

  11.             format.text { render 'other_text_welcome'  }  

  12.         end   

  13.     end   

  14. end    

6. ActiveRelation 以及 ActiveModel

rails2, 我们经常使用下面的方法来进行查询:

  1. @posts  = Post.find( :all ,  :conditions  => { :published  =>  true })  

该方式将立即查询数据库然后返回Posts 数组

而在rails3:

  1. @posts  = Post.where( :published  =>  true )  

该方法不会查询数据库, 仅仅返回一个 ActiveRecord::Relation 对象, 然后:

  1. @posts  = Post.where( :published  =>  true )  

  2. if  params[ :order ]  

  3.     @posts  =  @posts .order(params[ :order ])  

  4. end   

  5. @posts . each   do  |p|  

  6.     ...                 # 在这里进行查询 实现延迟加载   

  7. end   

对于命名范围, rails2:

  1. class  Post < ActiveRecord::Base  

  2.     default_scope :order  =>  'title'   

  3.     named_scope :published ,  :conditions  => { :published  =>  true }  

  4.     named_scope :unpublished ,  :conditions  => { :published  =>  false }  

  5. end   

而在rails3:

  1. class  Post < ActiveRecord::Base  

  2.     default_scope order('title' )  

  3.     scope :published , where( :published  =>  true )  

  4.     scope :unpublished , where( :published  =>  false )  

  5. end   

对于查找方法, rails2:

  1. Post.find( :all ,  :conditions  => { :author  =>  "Joe" },  :includes  =>  :comments ,  :order  =>  "title" ,  :limit  => 10)  

rails3:

  1. Post.where( :author  =>  "Joe" ).include( :comments ).order( :title ).limit(10).<strong><span style= "font-size:16px;" >all</span></strong>  

7. 跨站点脚本 (XSS)

rails2, 一般我们输入一段文本的时候, 我们往往会这样写: <%= h @post.body %>

那么在rails3, <%= @post.body %> 默认输出的是一段safe html, 如果想输出XSS, 可以在前面加上 raw

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值