_name "Andy"
last_name "Lindeman"
end
end
# spec/models/user_spec.rb
require "spec_helper"
describe User do
it "orders by last name" do
lindeman = create(:user)
chelimsky = create(:user, first_name: "David", last_name: "Chelimsky")
expect(User.ordered_by_last_name).to eq([chelimsky, lindeman])
end
end
Better Errors
gem "better_errors"
它用一个更好的,更有用的错误页替换标准的 Rails 错误页面,对 Rack middleware 也同样有效。
4百多万的下载,可见美观是很能吸引我们这些外观第一的程序员的。
gem "therubyracer"
gem "less-rails"
gem "twitter-bootstrap-rails"
来自 Twitter 的 Bootstrap,是一套完成的前台 CSS 框架。以简洁,优雅著称于世。被无数攻城狮所青睐,又让无数程序猿审美疲劳。不用不行啊~
分页控件
will_paginate
gem 'will_paginate', '~> 3.0.6'
Kaminari
gem 'kaminari'
Kaminari 支持多种的 ORM (ActiveRecord, Mongoid) 和多种的Web框架 (Rails, Sinatra, Grape), 以及多种的模板引擎 (ERB, Haml, Slim).
从数字上两者都只在伯仲之间,只是will_paginate 比较老, 应用案例较多, kaminari 更新, 性能和兼容性更好。
计划任务
有时候一些任务的执行会很慢,而这些任务我们并不要求需要马上返回结果 (比如:发送邮件,生成图片缩略图),那我们可以选择将这些任务放到后台执行,以便于页面不会长时间等待执行,我们还是将其统称为计划任务吧。
在这方面的有不少出色的 gem, 其粉丝也不在少数
Resque
gem 'resque', '~> 1.25', '>= 1.25.2'
Resque 是一个基于 Redis 的后台任务处理gem。后台工作可以是任何一个Ruby类或者模块。
Resque 相比于 DelayedJob 会是一个更加重型的gem。与 DelayedJob 的不同之处主要有三:
- 它是一个用于创建、查询、处理 的 Ruby 库
- 它是一个起动后台处理Worker的Rake任务。
- 它是一个Sinatra app 用于检测队列、工作和Workers.
class Archive
@queue = :file_serve
def self.perform(repo_id, branch = 'master')
repo = Repository.find(repo_id)
repo.create_archive(branch)
end
end
class Repository
def async_create_archive(branch)
Resque.enqueue(Archive, self.id, branch)
end
end
Sidekiq
gem 'sidekiq'
号称性能要比 Reque 和 delayed_job 都要高,具体的数据你可以上它们的 GitHub 上看,有一个完整的对比表。但明显在程序员的受欢迎度上还是要差于 Resque。
Resque 和 Sidekiq 都使用的 redis 作为任务数据存储,这块是差不多的,主要的区别还是在多任务处理的方式是不一样的。
resque 使用的是一个 worker 通过 fork 方式来产生多个 worker 处理多个任务,而 sidekiq 是一个 worker 使用的 Thread 方式产生多个线程 处理多个任务。
那 fork 方式和 thread 方式有什么区别呢?
fork 方式
fork 一个进程,操作系统会建立一个独立分开的地址空间,并且从父进程复制所有的内存片段到这个地址里面去。 这就意味着对于操作系统来说,对于 fork 的进程切换上下文,因为需要保存和加载所有数据,所以代价更大。 而且如果父进程死掉了,这些 fork 的子进程没有退出的话,将会变成僵尸进程。
thread 方式
多线程的话是共享地址空间,内存并且多线程之间的交互也比较方便。而且你也不用担心僵尸进程的问题,一旦进程死掉, 所有的线程会自动被杀掉。但这种方式也有缺点,你必须保证代码是线程安全的,不然可能会引起麻烦。
不难得出
- resque 比 sidekiq 更消耗内存
- resque 的 worker 代码没有必要担心线程安全问题,但 sidekiq 必须考虑
DELAYED_JOB
gem 'delayed_job_active_record'
DelayedJob 是一个轻量型的gem,使用起来也相当的简单,而且它可以配合一个 progress bars 控件检测任务的执行进度(可能这也是它除了轻量以外的最大特点)。
# without delayed_job
Notifier.signup(@user).deliver
# with delayed_job
Notifier.delay.signup(@user)
# with delayed_job running at a specific time
Notifier.delay(run_at: 5.minutes.from_now).signup(@user)
Whenever
gem 'whenever', :require => false
Linux 里面有 Cron 可以帮助我们定期执行一些任务,但是 Cron 手动写起来很是麻烦,尤其是前面时间周期的定义, Whenever 可以帮助我们用更人性化的方式编写 Cron 任务,看看出他的示例代码: