如何在rack的request请求中添加header

在rails的rspec测试中,测试请求一般是这样写的

describe API::V1::UsersAPI, type: :request do
    it 'test' do
    get '/api/v1/users/', nil, { Authorization: 'bear ' + token }
    expect(last_response.status).to eq(200)
  end
end

但在Rack::Test中不起作用, 因为参数都需要设置在env中,所以需要直接指定header

describe API::V1::UsersAPI do
    it 'test' do
    header 'Authorization', 'bearer ' + token 
    get '/api/v1/users/'
    expect(last_response.status).to eq(200)
  end
end

Module did not self-register 错误处理

最近node.js 和 io.js 分家, 造成了node-sass崩掉

*[develop][~/Projects/venus]$ ember s
version: 0.1.15
Livereload server on port 35729
Serving on http://0.0.0.0:4200/
Module did not self-register.
Error: Module did not self-register.
    at Error (native)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/Users/ZoOL/Projects/venus/node_modules/broccoli-sass/node_modules/node-sass/lib/index.js:181:15)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)

处理方法, 回退node版本

npm install -g n
n 0.10
node --version

在rails4与postgresql中使用uuid作为主键

安装步骤

先确保已经安装了 ruby on rails 和 postgresql

rails new uuids —database postgresql
rails generate migration enable_uuid_ossp_extension
rails generate model document title:string author:string

打开postgresql的uuid-ossp插件

class EnableUuidOsspExtension < ActiveRecord::Migration
  def change
    enable_extension uuid-ossp
  end
end

设置migration

class CreateDocuments < ActiveRecord::Migration
  def change
   create_table :documents, id: :uuid, default: 'uuid_generate_v4()'  do |t|
      t.string :title
      t.string :author
      t.timestamps
    end
  end
end

运行migration

rake db:create
rake db:migrate

安装完成

在console里测试一下

rails c

irb(main):011:0> Document.create(title: “PostgreSQL UUID!”, author: “Fox ZoOL”)
=> #<Document id: “ec31b888-a491-49e7-afa9-ab59e9131d78”, title: “PostgreSQL rocks!”, author: “Fox ZoOL”, created_at: “2015-01-10 21:02:17”, updated_at: “2015-01-10 21:02:17”>

Tips

由于主键已经是uuid了, Document.firstDocument.last 的返回值会出错,需要重写一下scope

class Document < ActiveRecord::Base
  scope :first, -> { order(created_at).first }
  scope :last, -> { order(created_at DESC).first }
end

mac下安装docker

步骤一: 安装 VirtualBox

用 brew-cask 安装 virtual box

$ brew update
$ brew tap phinze/homebrew-cask
$ brew install brew-cask
$ brew cask install virtualbox

步骤二: 安装 Docker 与 boot2docker

$ brew update
$ brew install docker
$ brew install boot2docker

步骤三: 初始化并启动boot2docker

$ boot2docker init
$ boot2docker up

步骤四: 设置docker环境变量

注意每个人的配置可能会有所不同

To connect the Docker client to the Docker daemon, please set:
    export DOCKER_CERT_PATH=/Users/ZoOL/.boot2docker/certs/boot2docker-vm
    export DOCKER_TLS_VERIFY=1
    export DOCKER_HOST=tcp://192.168.59.103:2376

步骤五: 测试

$ docker info

Containers: 0
Images: 0
Storage Driver: aufs
 Root Dir: /mnt/sda1/var/lib/docker/aufs
 Dirs: 0
Execution Driver: native-0.2
Kernel Version: 3.16.7-tinycore64
Operating System: Boot2Docker 1.4.1 (TCL 5.4); master : 86f7ec8 - Tue Dec 16 23:11:29 UTC 2014
CPUs: 8
Total Memory: 1.961 GiB
Name: boot2docker
ID: T4Z4:5EIE:6543:M53Y:YNN7:WMGE:UTZI:PUCR:ERDA:HQEB:U5RL:B5CA
Debug mode (server): true
Debug mode (client): false
Fds: 10
Goroutines: 11
EventsListeners: 0
Init Path: /usr/local/bin/docker
Docker Root Dir: /mnt/sda1/var/lib/docker

安装完成

BDD for Rails

安装组件

安装 RSpec

添加到Gemfile

group :development, :test do
  gem 'rspec-rails', '~> 3.0'
end

然后

$ bundle install

初始化RSpec目录

$ rails generate rspec:install

创建RSpec的binstub

$ bundle binstubs rspec-core

安装 Fuubar

fuubar 是一个使用进度条来表示RSpec测试进度的工具。
添加到Gemfile

group :test do
  gem 'fuubar'
end

运行

$ bundle install

将其设置为RSpec默认输出格式,编辑.rspec

—format Fuubar
—color

安装 shoulda-matchers

shoulda-matchers为RSpec扩充了很多rails内置方法的测试功能,不用自己重复写那些复杂的内置测试。
添加到Gemfile

group :test do
  gem 'shoulda-matchers'
end

运行

$ bundle install

安装 Factory Girl

Factory Girl是一个生成测试对象的工具
添加到Gemfile

group :development, :test do
  gem 'factory_girl_rails'
end

运行

$ bundle install

在RSpec配置文件spec_helper.rb添加配置

RSpec.configure do |config|
  .
  .
  .
  # Factory Girl

  config.include FactoryGirl::Syntax::Methods

end

在application.rb里添加下列配置

#add these lines

class Application < Rails::Application
    config.generators do |g|
      g.stylesheets false
      g.javascripts false
      g.test_framework :rspec,
        :fixtures => true,
        :view_specs => false,
        :helper_specs => false,
        :routing_specs => false,
        :controller_specs => true,
        :request_specs => true
      g.fixture_replacement :factory_girl, :dir => spec/factories
    end 
end

安装 Faker

faker 是一个生成测试数据的的工具, 如生成邮箱地址,手机号码,姓名
添加到Gemfile

group :test do
  gem 'faker'
end

运行

$ bundle install

安装 Database Cleaner

database cleaner可以确保每一次测试时,测试数据库都是干净的,没有干扰数据。
添加到Gemfile

group :test do
  gem 'database_cleaner'
end

运行

$ bundle install

给RSpec添加配置文件spec/spec_helper.rb

$ .
  .
  .
  RSpec.configure do |config|
  .
  .
  .
    # Database Cleaner

    config.before(:suite) do
      DatabaseCleaner.strategy = :transaction
      DatabaseCleaner.clean_with(:truncation)
    end
    config.before(:each) do
      DatabaseCleaner.start
      FactoryGirl.lint            # if FactoryGirl is installed !!!

    end
    config.after(:each) do
      DatabaseCleaner.clean
    end
  end

安装 Capybara-webkit

添加到Gemfile

group :test do
    gem capybara-webkit
end

运行

$ bundle install

在spec/spec_helper.rb里添加配置

.
.
require 'capybara/rspec'
.
Capybara.javascript_driver = :webkit
.
RSpec.configure do |config|
.

安装 spring

添加到Gemfile

group :development, :test do
  gem 'spring'
  gem 'spring-commands-rspec'
end

运行

$ bundle install
$ spring binstub —all

安装 SimpleCov

添加到Gemfile

group :test do
  gem 'simplecov', require: false
end

运行

$ bundle install

spec_helper.rb 第一行加载 simplecov

require 'simplecov' # if using simple simplecov

# see https://github.com/colszowka/simplecov#filters for filter/grouping etc

SimpleCov.start do  # for example…

  add_filter '/spec/'
  add_filter '/features/'
  add_filter '/config/'
  add_group 'Controllers', 'app/controllers'
  add_group 'Models', 'app/models'
  add_group 'Helpers', 'app/helpers'
  # add_group 'Views', 'app/views' # only .rb files are included at present!

  add_group 'Libraries', 'lib'
end
# Previous content of helper now start here

确保.gitignore里过滤下列目录

# Simplecov results
/coverage

安装guard

添加到Gemfile

group :development, :test do
  gem 'guard'
  gem 'guard-bundler'
  gem 'guard-rails'
  gem 'guard-rspec'
  gem 'guard-puma' # to have Guard use the Puma server rather than WEBrick

end

初始化Guardfile

$ guard init

安装完成

demo地址

使用.ruby-version控制项目中的ruby版本

ruby环境中有很多方式来控制ruby的版本,如rvm,chruby, rbenv, 每种各有自己的配置文件。
但现在已经各自统一了配置文件,使用.ruby-version来控制版本。

使用方法很简单, 在项目根目录下添加.ruby-version文件

echo ruby-2.2.0 > .ruby-version

ruby代码检查器rubocop

什么是RuboCop

Rubocop 是基于 ruby-style-guide / Ruby 风格指导 实现的一个静态代码分析工具。
使用rubocop有助于个人/团队写出风格统一的代码

如何安装

$ gem install rubocop

或使用bundle安装

gem 'rubocop', require: false

如何使用

$ rubocop

或指定目录或文件

$ rubocop app spec lib/tasks/something.rb

ruby-china为例

$ rubocop app/models/user.rb
app/models/user.rb:364:25: C: Prefer single-quoted strings when you don't need string interpolation or special symbols.
        description: a1["description"]
                        ^^^^^^^^^^^^^
app/models/user.rb:367:29: C: Space missing after comma.
    items = items.sort { |a1,a2| a2[:watchers] <=> a1[:watchers] }.take(14)
                            ^
app/models/user.rb:368:81: C: Line is too long. [85/80]
    Rails.cache.write(user.github_repositories_cache_key, items, expires_in: 15.days)
                                                                                ^^^^^
app/models/user.rb:371:3: C: Use only ascii symbols in comments.
  # 重新生成 Private Token

  ^^^^^^^^^^^^^^^^^^^^

1 file inspected, 181 offenses detected

竟然有181个地方需要修改!
其中有很多是 {:a => :b} 修改为 {a: :b}使用类似的问题
可以使用
rubocop自动化修复一部分, 加上-a`参数

$ rubocop -a app/models/user.rb

1 file inspected, 206 offenses detected, 149 offenses corrected

跑测试确认一下

rspec spec/models/user_spec.rb

✌,继续修改

app/models/user.rb:368:81: C: Line is too long. [85/80]
    Rails.cache.write(user.github_repositories_cache_key, items, expires_in: 15.days)
                                                                                ^^^^^
app/models/user.rb:371:3: C: Use only ascii symbols in comments.
  # 重新生成 Private Token

  ^^^^^^^^^^^^^^^^^^^^

又是警告, 但我想写中文注释,一行80个字太短了,我们修改一下rubocop配置。

.rubocop.yml

AllCops:

  RunRailsCops: true

Include:

  - '**/Gemfile'

  - '**/Rakefile'

Exclude:

  - 'bin/*'

  - 'db/migrate/*'

  - 'db/seeds.rb'

  - 'db/schema.rb'

  - 'vendor/bundle/**/*'

  

Metrics/LineLength:

  Max: 120

Style/AsciiComments:

  Enabled: false

再看一下

$ rubocop app/model/user.rb

app/models/user.rb:343:3: C: Assignment Branch Condition size for fetch_github_repositories is too high. [29.9/15]
  def self.fetch_github_repositories(user_id)
  ^^^
app/models/user.rb:343:3: C: Method has too many lines. [23/10]
  def self.fetch_github_repositories(user_id)
  ^^^

1 file inspected, 23 offenses detected

这样, 要修复的就少多了。

剩下的问题如Method has too many lines. [23/10]的警告就看你自己的想法了。
可以参考官方配置
.rubocop.yml里进行配置.

编辑器支持

vim, emacs, sublime, atom, rubymine全部支持
参考第三方支持

ruby 中的八进制

  • 八进制表示方式 用o代表无符号八进制
> irb                                                                                                                                                
2.2.0 :001 > puts 0233, 0o233, 0O233
155
155
155
  • 十进制转八进制
> irb                                                                                                                                                
2.2.0 :001 > 233.to_s(8)
 => "351"
  • 文本转八进制
> irb                                                                                                                                                
2.2.0 :001 > "11".to_i(8)
 => 9
2.2.0 :002 > "11".to_i(8) == 011
 => true

如何在model中使用url_helpers

如果想在model中使用类似 url_path 这样的helper方法, 可以这样:

class User < ActiveRecord::Base

  include Rails.application.routes.url_helpers
  .....
  def base_url
     user_path(self)
  end
  
  end