Ruby On Rails 經常使用的精品Gem彙總

首先須要註明一點,本文是原創的並非從其它地方轉載。全部的數據是我從 GitHub 和 RubyGems 上碼下來的,數據的截取時間就是本文的發佈日期。java

RubyGems 的下載量能夠看到在用這個 gem 的人數,因此數值很大(這裏收藏的下載量至少會大於10萬級)。而在 GitHub 上的則表明關注這個gem的源碼的人數(本文收藏的至少是過 1k以上 Star 的 repository)git

Nokogiri

gem 'nokogiri'

採集數據是咱們須要解析複雜的 HTML 結構,從中得到須要的數據,Nokogiri 能夠幫助咱們完美的處理不一樣網頁上面不一樣的 HTML 結構,而且有很好的編碼處理能力,用它你不用擔憂頁面是 GB2312 仍是 GBK 仍是 UTF-8,它都很很好的處理,解析結構能夠用相似 jQuery 的 CSS Selector 的方式查找,非常方便。曾經用過 Ruby 的好幾個相似插件,最終發現 Nokogiri 纔是最好的。程序員

Faraday

gem 'faraday', '~> 0.9.1'

Faraday 是一個HTTP的客戶端,能夠提供通常化的接口和多種的適配器 (例如 Net::HTTP)。github

作一些網絡服務API集成它是一個很好用的助手。redis

conn = Faraday.new(:url => 'http://sushi.com') do |faraday|
  faraday.request  :url_encoded             # form-encode POST params
  faraday.response :logger                  # log requests to STDOUT
  faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
end

## GET ##
response = conn.get '/nigiri/sake.json'     # GET http://sushi.com/nigiri/sake.json
response.body

conn.get '/nigiri', { :name => 'Maguro' }   # GET http://sushi.com/nigiri?name=Maguro

conn.get do |req|                           # GET http://sushi.com/search?page=2&limit=100
  req.url '/search', :page => 2
  req.params['limit'] = 100
end

## POST ##
conn.post '/nigiri', { :name => 'Maguro' }  # POST "name=maguro" to http://sushi.com/nigiri

# post payload as JSON instead of "www-form-urlencoded" encoding:
conn.post do |req|
  req.url '/nigiri'
  req.headers['Content-Type'] = 'application/json'
  req.body = '{ "name": "Unagi" }'
end

## Per-request options ##

conn.get do |req|
  req.url '/search'
  req.options.timeout = 5           # open/read timeout in seconds
  req.options.open_timeout = 2      # connection open timeout in seconds
end

RSPEC-RAILS

gem 'rspec-rails', '~> 3.4'

若是沒有用過 RSpec 都不能算是懂 Ruby 吧,respec_rails 顧名思義是將 rspec 集成至 rails 中的測試框架了:json

require "spec_helper"

describe User do
  it "orders by last name" do
    lindeman = User.create!(first_name: "Andy", last_name: "Lindeman")
    chelimsky = User.create!(first_name: "David", last_name: "Chelimsky")

    expect(User.ordered_by_last_name).to eq([chelimsky, lindeman])
  end
end

Devise

gem 'devise', '~> 3.5', '>= 3.5.2'

Devise 是一個用於快速構建基本用戶功能,如:註冊,登錄,找回密碼。 同時它還集成了第三方的登入支持,代碼也至關簡單:bootstrap

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable, :confirmable, :recoverable, stretches: 20
end

Devise 是一個大集成包,單看看它集成了什麼就能知道到大至上的功能了:api

  • Database Authenticatable: 支持加密的身份驗證並能將驗證信息存儲於數據內。
  • Omniauthable: 集成 OmniAuth 實現三方平臺(如: Twitter, Facebook, 新浪微博, 騰訊 QQ)帳號登錄的支持。
  • Confirmable: 發送郵件以驗證註冊用戶的身份。
  • Recoverable: 支持密碼重置。
  • Registerable:支持註冊新用戶。
  • Rememberable: 支持自動登陸
  • Trackable: 可跟蹤用戶的登入次數,時間戳和 IP
  • Timeoutable: 支持自動用戶會話的過時
  • Validatable: 可驗證用戶的郵件的與密碼的正確性,且可定製化。
  • Lockable: 能夠鎖定屢次嘗試登陸失敗的用戶帳號。

若是沒有它,光想一想要咱們本身來碼上面的這些功能都夠浪費時間的。重點是每一個項目都得用啊。安全

FACTORY_GIRL_RAILS

gem 'factory_girl_rails'

Factory Girl多是ROR測試中最經常使用到的數據工廠,沒有它也只能手工寫Fixture了。不解釋了,它太經常使用了。ruby

# spec/factories/user.rb
FactoryGirl.define do
  factory :user do
    first_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百多萬的下載,可見美觀是很能吸引咱們這些外觀第一的程序員的。

twitter-bootstrap-rails

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 任務,看看出他的示例代碼:

every 3.hours do
  runner "MyModel.some_process"
  rake "my:rake:task"
  command "/usr/bin/my_great_command"
end

every 1.day, :at => '4:30 am' do
  runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
end

every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
  runner "SomeModel.ladeeda"
end

every :sunday, :at => '12pm' do # Use any day of the week or :weekend, :weekday
  runner "Task.do_something_great"
end

every '0 0 27-31 * *' do
  command "echo 'you can use raw cron syntax too'"
end

# run this task only on servers with the :app role in Capistrano
# see Capistrano roles section below
every :day, :at => '12:20am', :roles => [:app] do
  rake "app_server:task"
end

它的 DSL 很簡單,直接,暴力易懂!

我我的是推薦使用 Resque 的。

上傳組件

Paperclip

gem "paperclip", "~> 4.3"

Paperclip 是老牌產品了,也是幾乎絕大多數項目都有在用它,它能夠幫你處理上傳圖片,裁減,定義不一樣的圖片尺寸,幾乎很完美。(with the support of ImageMagick)

# Rail4
class User < ActiveRecord::Base
  has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
  validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/
end

Carrierwave

gem 'carrierwave'

Carrierwave 是後起之秀,功能和 Paperclip 差很少,但它還能夠管理除圖片以外的東西,並且靈活性更高。

對比

Paperclip 官方只支持 ActiveRecord 但相對穩定, 而 Carrierwave 比較靈活支持更多的 ORM, 好比 mongoid

If you feel adventurous, you can try refile from the creators of carrierwave.

表單

Rails 爲咱們帶來和一改傳統的表單構件方式,可是通過實際的使用,咱們漸漸發覺這樣依然仍是不夠「敏捷」,咱們須要更加簡便並具備更細緻規範的表單,因此有了 Formtastic ,它用起來比 Rails 默認的 form 更加簡潔,可是卻具備更多的功能,你能夠爲每一個字段設定 help-text 放到文本框下面,並能夠走 I18n 的方式設置語言。simple_form 和 Formtastic 功能相似,但它的寫法還要簡單一些。

SIMPLE_FORM

gem 'simple_form'

SimpleForm 在用法上與 Formtastic 相似,一樣很好的支持了I18n、表間關聯、嵌套表單和表單驗證等經常使用的功能。SimpleForm 從 2.0 開始,在可定製性上有質的突破(Twitter Bootstrap 在裏邊起了很關鍵的做用),如今的它更像是一個 Form Builder 框架,能夠很方便的對它進行設置和擴展。

看看 simple_form 的用法 :

= simple_form_for @user do |f|
  = f.input :username, label: 'Your username please'
  = f.input :password, hint: 'No special characters.'
  = f.input :email, placeholder: 'user@domain.com'
  = f.input :remember_me, inline_label: 'Yes, remember me'
  = f.button :submit

Formtastic

gem 'formtastic', '~> 3.0'

Formtastic 的主要缺點在於對HTML輸出的可定製性上不夠靈活。目前的系統中,想要知足各類表單的需求,就須要在每一個表單頁寫不少重複的代碼進行設置,甚至不少頁面都在使用 Rails 原生的 Form Builder,這樣作維護量太大。

<%= semantic_form_for @post do |f| %>
    <%= f.inputs do %>
      <%= f.input :title %>
      <%= f.input :body %>
      <%= f.input :section, :as => :radio %>
      <%= f.input :categories %>
      <%= f.input :created_at, :as => :string %>
    <% end %>
    <%= f.actions do %>
      <%= f.action :submit, :as => :button %>
      <%= f.action :cancel, :as => :link %>
    <% end %>
  <% end %>

Grape

gem 'grape'

隨着 Mobile App 的增多,不少時候咱們在作用 Rails 作 API Base 項目時,rails 自帶的 C 和 V 層顯得過於繁雜,grape 能夠幫助咱們快速的構建和 Rails 完美融合的 API 接口。

module Twitter
  class API < Grape::API
    version 'v1', using: :header, vendor: 'twitter'
    format :json
    prefix :api

    helpers do
      def current_user
        @current_user ||= User.authorize!(env)
      end

      def authenticate!
        error!('401 Unauthorized', 401) unless current_user
      end
    end

    resource :statuses do
      desc 'Return a public timeline.'
      get :public_timeline do
        Status.limit(20)
      end

      desc 'Return a personal timeline.'
      get :home_timeline do
        authenticate!
        current_user.statuses.limit(20)
      end

      desc 'Return a status.'
      params do
        requires :id, type: Integer, desc: 'Status id.'
      end
      route_param :id do
        get do
          Status.find(params[:id])
        end
      end

      desc 'Create a status.'
      params do
        requires :status, type: String, desc: 'Your status.'
      end
      post do
        authenticate!
        Status.create!({
          user: current_user,
          text: params[:status]
        })
      end

      desc 'Update a status.'
      params do
        requires :id, type: String, desc: 'Status ID.'
        requires :status, type: String, desc: 'Your status.'
      end
      put ':id' do
        authenticate!
        current_user.statuses.find(params[:id]).update({
          user: current_user,
          text: params[:status]
        })
      end

      desc 'Delete a status.'
      params do
        requires :id, type: String, desc: 'Status ID.'
      end
      delete ':id' do
        authenticate!
        current_user.statuses.find(params[:id]).destroy
      end
    end
  end
end

CANCANCAN

gem 'cancancan', '~> 1.10'

它是 CanCan 項目的代替品,它其實就是爲咱們的應用加入操做權限控制,並且比較好的地方是能夠將全部的操做權限放在至到一個獨立的文件之中。

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end
end

而它的另外一個比較新後來者就能夠數 pundit 了, 因爲在RubyGems上的下載量才7萬多,因此就不獨列出數了。但值得注意的是它在GitHub上的start是6K多,已超越CanCanCan的Repository。

若是有作過操做權限控制的朋友可能都會發現,操做極權限控制是很耗費性能的,而 pundit 則號稱在性能上會超越 CanCanCan,

Pundit 更爲模塊化,對於體量較大的程序我以爲更爲之合適,至少不會寫出一個幾百行的大文件出來,不利於維護。

ActiveAdmin

gem 'activeadmin', github: 'activeadmin'

這是一個至關不錯的管理界面應用gem, 基本不須要作什麼需求就能上項目了。從RubyGems的百萬級下載量也能夠得知其受歡迎的程度了。感受上是有點仿 Wordpress 的 Dashboard。

我我的是很喜歡 ActivateAdmin 的DSL定義的,由於既簡單又快速:

ActiveAdmin.register Product do
    scope :all, default: true
    scope :available
    scope :drafts

    filter :title
    filter :author, as: :select, collection: ->{ Product.authors }
    filter :price
    filter :create_at

    index do
        column :title
        column "Price", sortable: :price do |product|
            number_to_currency product.price
        end
        defualt_actions
    end
end

這樣的代碼幾乎就是秒懂,不解釋了。這傢伙誰用誰說好 ^_^

他們的官網也作得挺好的,這裏是一些關於 ActivateAdmin 的資源連接:

  • 網站: http://www.activeadmin.info
  • 在線示例: http://demo.activeadmin.info/admin

相關 gem

rails_admin

$ rails g rails_admin:install

與 ActiveAdmin 相比 rails_admin 就遜色的多了,但在 GitHub 上卻表現不俗。在代碼質量上其實二者相去不遠,只是 ActiveAdmin 更好看一些,而 rails_admin 的界面就作得有點渣,要上項目的話必須得做出不少的修改。

如下是 rails_admin 的特點:

  • 對任何數據均可支持 CRUD
  • 自定義操做
  • 自動化表單驗證
  • 支持查找與過濾
  • 能夠將數據導出爲 CSV/JSON/XML 格式
  • 支持 Devise 的身份驗證
  • 支持 CanCanCan 或 Pundit 的權限斷定
  • 經過 PaperTrail 支持用戶操做歷史
  • 支持多種ORM
    • ActiveRecord
    • Mongoid

Sunspot

gem 'sunspot_rails'
gem 'sunspot_solr' # optional pre-packaged Solr distribution for use in development

Sunspot 是一個 Solr 搜索引擎的 Ruby 庫。它基於 RSolr 庫構建,提供低級別的 Solr 集成接口。它的定義很簡單,使用也至關容易,用DSL就可索引對象和啓用搜索了。

它的主要特色:

  • 全文搜索
  • ActiveRecord
  • 英文分詞

ActivateRecord 定義 可搜索對象

class Post < ActiveRecord::Base
  searchable do
    text :title, :body
    text :comments do
      comments.map { |comment| comment.body }
    end

    boolean :featured
    integer :blog_id
    integer :author_id
    integer :category_ids, :multiple => true
    double  :average_rating
    time    :published_at
    time    :expired_at

    string  :sort_title do
      title.downcase.gsub(/^(an?|the)/, '')
    end
  end
end

搜索

Post.search do
  fulltext 'best pizza'

  with :blog_id, 1
  with(:published_at).less_than Time.now
  order_by :published_at, :desc
  paginate :page => 2, :per_page => 15
  facet :category_ids, :author_id
end

小結

我這裏沒有列出 Rails 生成的那些經常使用 gem ,以上的都是一些我收集和經常使用的 gem 但願能對你們有用。

另外,若是您收藏了更好的 gem 但願能在本文留評,並且請註明 gem 的做用和 RubyGems 上的下載連接,給更多的Ruby的愛好者一個綜合性的資源彙總,Thanks!

相關文章
相關標籤/搜索