`
solaz3
  • 浏览: 73129 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

Rails3教程系列之六:从Rails2到Rails3

阅读更多

出处: oreilly

 

趁着上班前写一段 @@

 

那么从前面的教程中我们学习了如何创建一个简单的博客应用, 我个人觉得无论你是新手还是从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

 

Rails::Initializer.run do |config|
    config.load_paths += %W( #{RAILS_ROOT}/extras )
    config.gem "bj"
    config.gem "sqlite3-ruby", :lib => "sqlite3"
    config.gem "aws-s3", :lib => "aws/s3"
    config.plugins = [ :exception_notification ]
    config.time_zone = 'UTC'
end

 

 

rails3:config/application.rb

 

module APP_NAME
    class Application < Rails::Application
        config.load_paths += %W( #{RAILS_ROOT}/extras )
        config.plugins = [ :exception_notification ]
        config.time_zone = 'UTC'
    end
end

 

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

 

3. 路由

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

在 rails2 中:

map.resources :posts do |post|
    post.resources :comments
end

 而在rails3中, 表达更为形象:

resources :posts do
    resources :comments
end

 

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

post.resources :comments,
                 :member => { :preview => :post },
                 :collection => { :archived => :get }

 在rails3中可以这样表达:

resources :comments do
    member do
        post :preview
    end
    collection do
        get :archived
    end
end

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

resources :comments do
    post :preview, :on => :member
    get :archived, :on => :collection
end

 

对于基本路由, rails2:

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

 那么在rails3中:

match 'login' => 'session#new'

 

对于具名路由, rails2:

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

在rails3中:

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

 

对于程序根路由, rails2:

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

 rails3:

root :to => 'users#index'

 

对于遗留路由, rails2:

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

 那么在rails3中写法更优雅:

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

 

对于路由参数, rals2:

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

 rails3:

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

 

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

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

 在rails3中:

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

 

指定请求方式, rails2:

map.connect '/articles/:year', :controller => 'posts', :action => 'index',
:conditions => {:method => :get}

 在rails3中:

match '/articles/:year' => "posts#index", :via => :get
#或者更简单的:
get '/articles/:year' => "posts#index"

 

对于跳转, rails3:

match 'signin', :to => redirect("/login")
match 'users/:name', :to => redirect {|params| "/#{params[:name]}" }
match 'google' => redirect('http://www.google.com/')

 

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

map.connect '/:year', :controller => 'posts', :action => 'index',
                                    :requirements => { :year => /\d{4}/ }

 在rails3中:

match '/:year' => "posts#index", :constraints => {:year => /\d{4}/}
:constraints => { :user_agent => /iphone/ }
:constraints => { :ip => /192\.168\.1\.\d{1,3}/ }
constraints(:host => /localhost/) do
    resources :posts
end
constraints IpRestrictor do
    get 'admin/accounts' => "queenbee#accounts"
end

 

对于Rack应用, rails3:

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

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

get 'rack_app' => CustomRackApp
 

4. Bundler与ActionController

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

config.gem "haml"
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

gem "haml"
gem "chronic", '0.2.3'

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

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

 

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

 

 

一般的控制器语法:

class UsersController < ApplicationController
    def index
        @users = User.all
        respond_to do |format|
            format.html
            format.xml { render :xml => @users.to_xml } 
        end
    end

    def show
        @user = User.find(params[:id])
        respond_to do |format|
            format.html # show.html.erb
            format.xml { render :xml => @user }
        end
    end

...

 

改进的语法:

class UsersController < ApplicationController
    respond_to :html, :xml, :json
    def index
        @users = User.all
        respond_with(@users)
    end
    def show
        @user = User.find(params[:id])
        respond_with(@user)
    end
...



 

 

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:

def welcome(user, subdomain)
    subject 'Welcome to TestApp'
    recipients user.email
    from 'admin@testapp.com'
    body :user => user, :subdomain => subdomain
end
UserMailer.deliver_welcome(user, subdomain) 

在rails3中:

def welcome(user, subdomain)
    @user = user
    @subdomain = subdomain
    mail(:from => "admin@testapp.com",
            :to => user.email,
            :subject => "Welcome to TestApp")
end
UserMailer.welcome(user, subdomain).deliver

 

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

class UserMailer < ActionMailer::Base
    default :from => "admin@testapp.com",
                :reply_to => "noreply@testapp.com",
                "X-Time-Code" => Time.now.to_i.to_s
    def welcome(user, subdomain)
        @user = user
        @subdomain = subdomain
        attachments['test.pdf'] = File.read("#{Rails.root}/public/test.pdf")
        mail(:to => @user.email, :subject => "Welcome to TestApp") do |format|
            format.html { render 'other_html_welcome' }
            format.text { render 'other_text_welcome' }
        end
    end
end 

 

 

6. ActiveRelation 以及 ActiveModel

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

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

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

 

而在rails3中:

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

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

@posts = Post.where(:published => true)
if params[:order]
    @posts = @posts.order(params[:order])
end
@posts.each do |p|
    ...                 #在这里进行查询, 实现延迟加载
end

 

对于命名范围, 在rails2中:

class Post < ActiveRecord::Base
    default_scope :order => 'title'
    named_scope :published, :conditions => {:published => true}
    named_scope :unpublished, :conditions => {:published => false}
end

而在rails3中:

class Post < ActiveRecord::Base
    default_scope order('title')
    scope :published, where(:published => true)
    scope :unpublished, where(:published => false)
end

 

对于查找方法, rails2:

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

 在rails3:

Post.where(:author => "Joe").include(:comments).order(:title).limit(10).all

 

 

7. 跨站点脚本(XSS)

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

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

 

分享到:
评论

相关推荐

    Rails的精简版本Rails::API.zip

    Rails::API 是 Rails 的精简版本,针对不需要使用完整 Rails 功能的开发者。 Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails ...

    Rails上的API:使用Rails构建REST APIAPIs on Rails: Building REST APIs with Rails

    3. **社区活跃**:Rails拥有庞大的开发者社区,提供了丰富的插件和教程资源,遇到问题时可以迅速获得帮助。 4. **安全性**:Rails内置了一系列安全措施,比如防止SQL注入、XSS攻击等,有助于保护应用免受常见威胁。 ...

    rails学习教程

    本“rails学习教程”PDF文档将涵盖以上所有内容,通过详尽的实例和解释,帮助你从新手到熟手,全面掌握Rails开发。无论是想从事Web开发职业,还是想要提升个人项目开发能力,这都是一份不可多得的学习资料。

    中文版rails教程

    3. **路由(Routing)**:Rails的路由系统根据URL映射到特定的控制器和动作,定义了应用的导航结构。 4. **测试驱动开发(Test-Driven Development, TDD)**:Rails鼓励使用TDD,提供了Rspec和Capybara等强大的测试...

    Flexible Rails: Flex3 on Rails2

    ### Flexible Rails: Flex3 on Rails2 #### 关于Flexible Rails 本书《Flexible Rails: Flex 3 on Rails 2》由Peter Armstrong撰写,旨在探讨如何结合使用Flex 3和Rails 2来开发高效的富互联网应用程序(Rich ...

    ruby on rails 教程源码

    通过这个教程源码,你不仅可以学习到基本的Web开发知识,还能深入了解Rails框架的精髓,提高开发效率。记得实践是检验真理的唯一标准,动手操作并结合理论学习,你将能更好地掌握这个强大的Web开发工具。

    Rails中应用Ext.tree:以中国的省市地区三级联动选择为例

    在Ruby on Rails(Rails)框架中,开发人员经常需要实现各种用户交互功能,例如三级联动选择,这在处理如中国省市区这样的地理数据时尤其常见。这篇博客文章“Rails中应用Ext.tree:以中国的省市地区三级联动选择为...

    ruby on rails视频教程

    ruby on rails视频教程 链接:https://pan.baidu.com/s/10eKsJLllLySXk-b5muV_Qw 密码见文件

    Ruby on Rails安装指南(Ruby 1.8.6+Rails 2.0.2)

    知识点3:Mongrel 安装 * 下载 Mongrel 1.1.4 版本 * 安装 Mongrel * 安装所需插件(gem plugin、daemons、fastthread、cgi_multipart_eof_fix) 知识点4:创建 Rails 应用程序 * 创建测试的 Rails 应用程序 * ...

    Rails入门教程一(翻译).pdf

    《Rails入门教程一》是针对初学者的一份详尽指南,旨在帮助读者快速掌握Ruby on Rails框架的基础知识。Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式...

    Ruby On Rails教程

    ### Ruby on Rails 教程知识点概述 #### 一、引言 - **敏捷开发与Rails:** 本书《Ruby on Rails教程》强调了Rails作为敏捷开发框架的优势。它旨在帮助开发者快速构建高质量的Web应用程序。 - **作者团队:** 本书...

    Ruby on Rails Guides v2 - Ruby on Rails 4.2.5

    ### Ruby on Rails Guides v2 - Ruby on Rails 4.2.5 #### 一、重要概念及基础假设 - **重要概念**:本指南旨在帮助读者深入理解Ruby on Rails(以下简称Rails)4.2.5版本的核心功能与最佳实践。 - **基础假设**:...

    Rails3常用命令行命令

    Rails3 是 Ruby on Rails 框架的一个版本,它提供了一系列强大的命令行工具,使得开发者可以快速地构建和管理Web应用。在本文中,我们将深入探讨Rails3中的常用命令,帮助你更高效地进行开发工作。 首先,新建一个...

    Ruby on Rails 教程 - 201406

    本教程“Ruby on Rails 教程 - 201406”可能是针对2014年6月时的Rails版本,那时候Rails正处于3.x或4.x系列,虽然现在Rails已经发展到6.x版本,但基础概念和核心原则依然适用。 在Rails中,Model负责处理数据和业务...

Global site tag (gtag.js) - Google Analytics