`
fanjunt
  • 浏览: 2349 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

Rails3学习笔记一,中秋假期

阅读更多
好久没有写代码了,手痒得很。面对即将到来的长假,打算把Rails3好好的学习一把,鉴于自己Rails2也是菜鸟水准,首先端正态度,好好学习,天天向上。其次学习方法论依旧是战争中学习战争,先拿公司的一个内部项目开刀。

废话不说,
引用
Terminal=》ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]

OK,符合Rails3的要求,更新Gems。。。。。

首先看看rails命令的帮助 rails -h,看看都有什么
引用
Usage:
  rails new APP_PATH [options]
  -J, [--skip-prototype]      # Skip Prototype files
  -T, [--skip-test-unit]      # Skip Test::Unit files

额额,Prototype换成我更熟悉的Jquery,Test::Unit换成Rspec,好就这么办
引用
rails new Capricorn -TJ
mate .

代码生成完毕,看了一下public/javascripts/下面的controls.js,dragdrop.js,effects.js,prototype.js是没有的;同时test目录也是没有的。

第二件事情,处理Gemfile,这个比较好理解,就是Ruby的Maven

gem 'unicorn'
gem 'haml-rails'
gem 'jquery-rails'
group :development, :test do
  gem "rspec-rails", ">= 2.0.0.beta.22"
  gem 'autotest'
  gem 'rails3-generators'
  gem 'factory_girl_rails'
  gem 'webrat'
end


unicorn是类似Mongrel的一个东东,特点在于socket,以及kill -USR2 master_pid master的类似Nginx的启动方式让我很心仪。
haml-rails和jquery-rails是从rails3-generators分离出来的,针对Rails3和Haml以及Jquery的特方便集成。
rspec-rails就不用说了。
autotest会自动监视你的代码的改动,自动运行测试,所以你只要Command+t一个Terminal窗口就好。
rails3-generators的存在就是为了factory_girl_rails,后者是替换Rails3自带的fixtures的。
webrat也没什么好说的。

运行
引用
bundle install

配置依赖

安装rspec
引用
rails g rspec:install
{
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  autotest
      create  autotest/discover.rb
}


安装Jquery
引用
rails g jquery:install
{
      remove  public/javascripts/controls.js
      remove  public/javascripts/dragdrop.js
      remove  public/javascripts/effects.js
      remove  public/javascripts/prototype.js
      create  public/javascripts/jquery.min.js
      create  public/javascripts/jquery.js
      create  public/javascripts/rails.js
}


配置factory_girl,修改application.rb,添加
config.generators do |g|
  g.fixture_replacement :factory_girl, :dir => "spec/factories"
end


修改rspec_helper.rb,替换
config.fixture_path = "#{::Rails.root}/spec/factories"


接下来,该干真格的了,先干用户登录模块
引用
rails g model User login:string name:string email:string crypted_password:string salt:string

查看输出结果为
引用
      invoke  active_record
      create    db/migrate/20100924033208_create_users.rb
      create    app/models/user.rb
      invoke    rspec
      create      spec/models/user_spec.rb
      invoke      factory_girl
      create        spec/factories/users.rb


额额,从结果来看,Rspec和Factory_girl是配置OK的。
Java的TDD经验告诉我,先从user_spec.rb下手。额额,Ruby代码写起来比较不给力啊,千言万语不知从何说起,TMD先用JAVA经验往上套吧,再看看别人的代码是怎么写的,能抄就抄,活人不能让尿憋死,罗马也不是一天就能建起来的,慢慢来。

  describe 'being created' do
    before do
      @user = nil
      @creating_user = lambda do
        @user = create_user
      end
    end

    it 'increments User#count' do
      @creating_user.should change(User, :count).by(1)
    end
  end

  protected

  def create_user(options = {})
    u = User.new({ :login => 'PenG', :email => 'PenG@example.com', :password => 'peng82', :password_confirmation => 'peng82' }.merge(options))
    u.save! if u.valid?
    u
  end

先这样,运行一下看看再说
引用
autotest

额额,找不到Users,哦,忘了rake db:migrate和rake db:test:prepare。连续两次Control+c中断autotest,再运行
引用
rake db:migrate
rake db:test:prepare
autotest

哦了!

在做一些老俗套的事情

  it 'requires login' do
    lambda do
      create_user(:login => nil).should_not be_valid
    end.should_not change(User, :count)
  end

  describe 'allows legitimate logins:' do
    ['123', '1234567890_234567890_234567890_234567890', 
      'hello.-_there@funnychar.com'].each do |login_str|
      it "'#{login_str}'" do
        lambda do
          u = create_user(:login => login_str)
          u.errors[:login].should be_empty
        end.should change(User, :count).by(1)
      end
    end
  end

  describe 'disallows illegitimate logins:' do
    ['12', '1234567890_234567890_234567890_234567890_', "tab\t", "newline\n",
      "Iñtërnâtiônàlizætiøn hasn't happened to ruby 1.8 yet", 
      'semicolon;', 'quote"', 'tick\'', 'backtick`', 'percent%', 'plus+', 'space '].each do |login_str|
      it "'#{login_str}'" do
        lambda do
          u = create_user(:login => login_str)
          u.errors[:login].should_not be_empty
        end.should_not change(User, :count)
      end
    end
  end

  it 'requires password' do
    lambda do
      u = create_user(:password => nil)
      u.should_not be_valid
    end.should_not change(User, :count)
  end

  it 'requires password confirmation' do
    lambda do
      u = create_user(:password_confirmation => nil)
      u.should_not be_valid
    end.should_not change(User, :count)
  end

  it 'requires email' do
    lambda do
      u = create_user(:email => nil)
      u.should_not be_valid
    end.should_not change(User, :count)
  end

  describe 'allows legitimate emails:' do
    ['foo@bar.com', 'foo@newskool-tld.museum', 'foo@twoletter-tld.de', 'foo@nonexistant-tld.qq',
      'r@a.wk', '1234567890-234567890-234567890-234567890-234567890-234567890-234567890-234567890-234567890@gmail.com',
      'hello.-_there@funnychar.com', 'uucp%addr@gmail.com', 'hello+routing-str@gmail.com',
      'domain@can.haz.many.sub.doma.in'].each do |email_str|
      it "'#{email_str}'" do
        lambda do
          u = create_user(:email => email_str)
          u.errors[:email].should be_empty
        end.should change(User, :count).by(1)
      end
    end
  end
  
  describe 'disallows illegitimate emails' do
    ['!!@nobadchars.com', 'foo@no-rep-dots..com', 'foo@badtld.xxx', 'foo@toolongtld.abcdefg',
      'Iñtërnâtiônàlizætiøn@hasnt.happened.to.email', 'need.domain.and.tld@de', "tab\t", "newline\n",
      'r@.wk', '1234567890-234567890-234567890-234567890-234567890-234567890-234567890-234567890-234567890@gmail2.com',
      'uucp!addr@gmail.com', 'semicolon;@gmail.com', 'quote"@gmail.com', 'tick\'@gmail.com', 'backtick`@gmail.com', 'space @gmail.com', 
      'bracket<@gmail.com', 'bracket>@gmail.com'].each do |email_str|
      it "'#{email_str}'" do
        lambda do
          u = create_user(:email => email_str)
          u.errors[:email].should_not be_empty
        end.should_not change(User, :count)
      end
    end
  end

  describe 'allows legitimate names:' do
    ['Andre The Giant (7\'4", 520 lb.) -- has a posse', 
      '', '1234567890_234567890_234567890_234567890_234567890_234567890_234567890_234567890_234567890_234567890'].each do |name_str|
      it "'#{name_str}'" do
        lambda do
          u = create_user(:name => name_str)
          u.errors[:name].should be_empty
        end.should change(User, :count).by(1)
      end
    end
  end
  
  describe "disallows illegitimate names" do
    ["tab\t", "newline\n",
      '1234567890_234567890_234567890_234567890_234567890_234567890_234567890_234567890_234567890_234567890_'].each do |name_str|
      it "'#{name_str}'" do
        lambda do
          u = create_user(:name => name_str)
          u.errors[:name].should_not be_empty
        end.should_not change(User, :count)
      end
    end
  end

以上代码皆抄自于restful_authentication,修改的地方就是u.errors处的API在Rails3中有改动。Rails3会返回[],也就是说原来这里的判定为be_nil是不行的,基本上都要改。

上述代码和我以前写的Rspec代码有3个明显的优点我认为,

  def clean_user(options = {})
    user = User.new({:name => 'Tom.Zhao', :email => 'Tom.Zhao@example.com', :password => 'Tom.Zhao'}.merge(options))
  end

  it 'should require name, email password' do
    clean_user(:name => '').should_not be_valid
    clean_user(:email => '').should_not be_valid
    clean_user(:password => '').should_not be_valid
  end

  it 'has lengh 5 ~ 40 of password' do
    clean_user(:password => '1234').should_not be_valid
    clean_user(:password => '1234' * 10 + '1' ).should_not be_valid
    clean_user(:password => '12345').should be_valid
    clean_user(:password => '1234' * 10).should be_valid
  end


1:由lambda匿名函数执行验证测试,并且返回一个Proc对象直接验证是否save!
2:大量的条件验证,[].each do |name_str|的用法出来的结果更直观,同时代码可读性更高一些。
3:对于在model中的validates:format => {:with => RE_EMAIL_OK, :message => MSG_EMAIL_BAD},可以直接验证返回的错误message。

测试写好了,我们该给model添加东西了,Rails3推出了validates可以让我们的写法更性感,它可以使用的参数为
引用
    * :acceptance => Boolean
    * :confirmation => Boolean
    * :exclusion => { :in => Ennumerable }
    * :inclusion => { :in => Ennumerable }
    * :format => { :with => Regexp }
    * :length => { :minimum => Fixnum, maximum => Fixnum, }
    * :numericality => Boolean
    * :presence => Boolean
    * :uniqueness => Boolean


修改user.rb

  include ApplicationHelper
 
  validates :login, :presence => true, 
                    :uniqueness => { :case_sensitive => false },
                    :length => {:minimum => 3, :maximum => 40},
                    :format => {:with => RE_LOGIN_OK, :message => MSG_LOGIN_BAD}
                    
  validates :email, :presence => true, 
                    :uniqueness => { :case_sensitive => false },
                    :length => {:minimum => 6, :maximum => 100},
                    :format => {:with => RE_EMAIL_OK, :message => MSG_EMAIL_BAD}
                    
  validates :name,  :length => {:maximum => 100},
                    :format => {:with => RE_NAME_OK, :message => MSG_NAME_BAD}
         
  validates :password,  :presence => true
  
  validates :password_confirmation,  :presence => true
                            
  attr_accessor :password, :password_confirmation


Rails3的新validates我十分喜欢,作用一目了然,并且十分性感。顺便说一下
:format => {:with => EmailRegexp}这里,针对常用的验证,比如Email,可以抽出来,在lib目录下新加一个email_validator.rb
class EmailValidator < ActiveModel::EachValidator

  EmailAddress = begin
    qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
    dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
    atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' +
      '\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
    quoted_pair = '\\x5c[\\x00-\\x7f]'
    domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
    quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
    domain_ref = atom
    sub_domain = "(?:#{domain_ref}|#{domain_literal})"
    word = "(?:#{atom}|#{quoted_string})"
    domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
    local_part = "#{word}(?:\\x2e#{word})*"
    addr_spec = "#{local_part}\\x40#{domain}"
    pattern = /\A#{addr_spec}\z/
  end

  def validate_each(record, attribute, value)
    unless value =~ EmailAddress
      record.errors[attribute] << (options[:message] || "is not valid") 
    end
  end
  
end

那这里的代码可以直接这样写
validates :email, :presence => true, 
                    :length => {:minimum => 3, :maximum => 254},
                    :uniqueness => true,
                    :email => true


回到目前代码中。
同时定义一些常量在ApplicationHelper中

  unless defined? CONSTANTS_DEFINED
      RE_LOGIN_OK     = /\A\w[\w\.\-_@]+\z/
      MSG_LOGIN_BAD   = "use only letters, numbers, and .-_@ please."

      RE_NAME_OK      = /\A[^[:cntrl:]\\<>\/&]*\z/
      MSG_NAME_BAD    = "avoid non-printing characters and \\&gt;&lt;&amp;/ please."

      RE_EMAIL_NAME   = '[\w\.%\+\-]+'
      RE_DOMAIN_HEAD  = '(?:[A-Z0-9\-]+\.)+'
      RE_DOMAIN_TLD   = '(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)'
      RE_EMAIL_OK     = /\A#{RE_EMAIL_NAME}@#{RE_DOMAIN_HEAD}#{RE_DOMAIN_TLD}\z/i
      MSG_EMAIL_BAD   = "should look like an email address."

      CONSTANTS_DEFINED = 'yup'
    end

保存之后,看到autotest窗口测试全部通过,OK!
接下来处理密码加密,以及Email激活,是用Rails3自带的状态机,还是用state_machine呢?这是个问题。

10月1号搞定下一步。
分享到:
评论
5 楼 飞语001 2010-10-01  
楼主国庆期间还在努力的学习,精神可嘉。
4 楼 t0uch 2010-09-26  
rails3的话直接抛弃rjs吧
3 楼 Hooopo 2010-09-25  
fanjunt 写道
还没研究到那里,嘿嘿(目前我这只菜鸟飞的很慢)。不过从朋友那边反馈到的情况是,RJS口碑不太好,没必要完全ROR风格,Javascript原来怎么用,就怎么用就好。Unobtrusive JavaScript又不是ROR发明的。后面我会自己好好研究一下。

嗯,从没用过rjs...还是直接写jquery好~
2 楼 fanjunt 2010-09-25  
还没研究到那里,嘿嘿(目前我这只菜鸟飞的很慢)。不过从朋友那边反馈到的情况是,RJS口碑不太好,没必要完全ROR风格,Javascript原来怎么用,就怎么用就好。Unobtrusive JavaScript又不是ROR发明的。后面我会自己好好研究一下。
1 楼 fansofjava 2010-09-25  
使用jquery的话,RJS是个有点麻烦的问题,jrails长久不更新了,一点也不好用。

相关推荐

    rails查询学习笔记

    描述中虽然没有具体信息,但我们可以推测这可能是一篇关于Rails中查询技巧和最佳实践的学习笔记,可能包括如何使用ActiveRecord查询接口进行复杂的数据库操作,如选择、过滤、排序、分组等。 标签 "源码" 暗示了这...

    rails 入门详细笔记

    rails官网入门笔记的翻译,非常不错的rubyonrails入门教程!

    rails3教程

    #### 一、Rails3简介与核心原则 **Rails3**是Ruby on Rails框架的一个重要版本,它对之前的版本进行了大量的改进和优化,使其更加强大和灵活。Rails3的核心设计理念围绕着几个关键的概念,这些概念不仅帮助开发者...

    Rails 101 入门电子书

    - 学习如何创建第一个Rails应用程序。 - **过程**: - 创建新项目。 - 设置数据库配置。 - 创建控制器和视图。 - 在浏览器中查看结果。 #### 六、Rails的路由 - **概念介绍**: 路由是连接用户请求URL与应用...

    Rails3常用命令行命令

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

    Rails 学习资料

    3. **路由**:学习Rails的路由系统,如何配置URL到控制器动作的映射。 4. **ActiveRecord**:这是Rails的ORM(对象关系映射),用于处理数据库操作,了解其基本用法和查询语句。 5. **视图模板**:掌握ERB...

    常用RAILS学习网站

    收集了常用RAILS学习的网址 收集了常用RAILS学习的网址

    ruby on rails 3 tutorial.pdf

    《Ruby on Rails 3 Tutorial》是一本专门为初学者设计的指南,旨在帮助读者快速掌握Ruby on Rails这一强大的Web开发框架。Ruby on Rails(简称Rails)是基于Ruby语言的一个开源框架,它采用MVC(Model-View-...

    rails学习教程

    学习如何将Rails应用部署到生产环境,如Heroku或AWS,是开发过程中必不可少的一部分。了解配置数据库、管理环境变量以及优化性能的方法。 本“rails学习教程”PDF文档将涵盖以上所有内容,通过详尽的实例和解释,...

    Ruby_On_Rails笔记

    综上所述,Ruby on Rails的笔记内容涵盖了从安装Rails环境到创建和运行一个简单的Rails项目的基础知识,这些内容对于初学者来说是学习Rails框架的极好入门材料。通过对这些知识点的学习,初学者可以快速了解Rails的...

    ruby on rails 笔记(陈刚)

    从给定的文件信息来看,这份文档是陈刚关于Ruby on Rails的学习笔记,旨在帮助初学者更好地理解并掌握Ruby on Rails这一流行的Web开发框架。以下是对文档中提及的关键知识点的详细解析: ### 安装与配置 #### Ruby...

    Rails 3 in Action

    《Rails 3 in Action》是2011年由Ryan Bigg撰写的一本关于Ruby on Rails框架的权威指南,专门针对当时最新的Rails 3.1版本进行了深入解析。这本书旨在帮助开发者充分利用Rails 3.1的强大功能,提升Web应用开发的效率...

    ruby on rails环境搭建学习笔记;passenger+nginx环境配置

    在进行 Ruby on Rails 的开发之前,首先需要完成一系列的基础软件安装工作,包括但不限于 Ruby 语言环境、Rails 框架、版本管理工具等。 ##### 安装基础依赖 1. **更新系统包列表:** ```sh sudo apt-get update...

    centOS Rails3环境搭建

    ### CentOS环境下Rails 3开发环境搭建详解 #### 一、准备工作与环境配置 ...通过以上步骤,您可以在CentOS系统上成功搭建一个完整的Rails 3开发环境。这对于初学者和专业开发者来说都是非常实用的知识点。

    rails_入门详细笔记(官网翻译).

    ### Rails 入门详细笔记知识点解析 #### 一、环境搭建 在开始使用 Rails 进行开发之前,首先需要确保你的开发环境满足以下条件: - **Ruby 版本**:推荐使用 Ruby 1.9.2 或更高版本。这是因为早期版本如 1.8.7 ...

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

    **Rails入门教程一(翻译).pdf** Rails,全称为Ruby on Rails,是一个基于Ruby语言的开源Web应用程序框架,遵循MVC(Model-View-Controller)架构模式,用于构建数据库驱动的web应用。本教程是针对初学者设计的,...

    ruby on rails 3

    Ruby on Rails 3 是一个基于Ruby编程语言的开源Web应用程序框架,它遵循MVC(Model-...提供的文档如"Ruby192和Rails3.0.3的新征程.doc"和"rails3入门教程.pdf"等,将有助于深入理解这一框架及其在实际项目中的应用。

    Ruby Rails 3 Linda

    在“Ruby Rails 3 Linda”这一主题中,我们将会深入探讨Rails 3版本的相关知识点。 1. **安装与设置**:首先,学习如何在本地环境中安装Ruby、RubyGems和Rails。Ruby版本管理器如RVM(Ruby Version Manager)或...

Global site tag (gtag.js) - Google Analytics