Edited at

Railsやるなら知っておきたい便利Gem

(リクルートライフスタイル Advent Calendar 2015 - Qiita の18日目)

@MomokoAsai です。ショプリエを担当してます。サーバーサイドエンジニアです。

業務でも個人でもRails4.2を使っておりまして

『今ってどのgemが良さ気なの?』を改めて調べてみたので、紹介したいと思います。

今まで使ってたgemが ”Rails4から標準モジュールに統合されているからいらない” とか ”開発がもう止まってる”

とかもあったので、参考にしていただければと。

ちょっとしたも、載せているものは載せているので、参考にしていただければと。

2015/12/18 現在


Gem の紹介


■ デスクトップ/スマートフォン のテンプレート出し分け



  • jpmobile => を、やめた

    → Rails4.1から標準機能で、variant が追加されたので、そっちを採用

いきなりgemじゃないけれど

例)

スマートフォン出し分け関数を作り

※ Rails4からは、controller, model以下にconcernsディレクトリが出来たので、そちらに。concernについては割愛


app/controllers/concerns/user_agent.rb

module UserAgent

extend ActiveSupport::Concern

def is_mobile?
request.user_agent =~ /iPhone|iPad|Android/
end
end


スマートフォンなら:smart に振り分けられるように書く


app/controllers/application_controller.rb

class ApplicationController < ActionController::Base

include UserAgent

protect_from_forgery with: :exception

before_action :detect_device_variant
private
def detect_device_variant
request.variant = :smart if is_mobile?
end
end


こうすると、参照するテンプレートを設定した形式で分けてくれます。

#今回は「smart」で出し分け

app/views/show.html+smart.erb

app/views/show.html.erb


■ 画像アップロード機能

refilecarrierwaveの作者が作った後継 gemです。

carrierwaveに欲しかった機能が盛り込まれています。


  • s3へのブラウザから直接アップロードのサポート

  • サムネイルの動的生成サポート

などなど

carrierwaveと同じ作者ということもあり、これは安心かつ嬉しいですね。

日本語の情報はまだまだ少ないです。

他の画像アップロードのgemは有名ドコロとして carrierwavepaperclipがあります。

それぞれ簡単に比較するとこんな感じ。

gem
こんな人
特徴

CarrierWave
凝ったことをやりたい
多機能、柔軟性の高い

Paperclip
シンプルな機能を手早く実装したい
シンプル

参考:http://blog.inouetakuya.info/entry/20131014/1381749488


■ ABテスト

前にいたチーム(ギャザリー)で、

このgemを使ってABテストを行っていました。大変お世話になったgemさんです。

これを使うと、ユーザーSession毎に表示や処理の出し分けが出来るようになります。

さらに、「何%をAパターンに割り当てるか?」の指定も簡単に出来てしまいます。

Split uses redis as a datastore.

READMEにもある通り、redisを使ってこれらを実現してるので、redisを用意しましょう。

例)

基本、下の2つメソッドで事足ります。

finishedは、コンバージョン達成を特に設けない場合は必要ないです。

メソッド  
内容  

ab_test
ABテストの開始時に呼び出す (ユーザー振り分け&Session関連をRedisに保存)

finished
コンバージョン達成時に呼び出す (Session関連をリセット)

では、いきます。

画像出しわけだけであれば、これだけで完了です。

<% ab_test(:login_button, "/images/button1.jpg", "/images/button2.jpg") do |button_file| %>

<%= image_tag(button_file, alt: "Login!") %>
<% end %>

もう少しいろいろやりたい・何種類もやりたい場合は、

設定ファイルを用意して、出し分け毎にif文などでくくってしまうと、いろいろ出来ます。

Split.configure do |config|

config.experiments = YAML.load_file "config/experiments.yml"
end


config/experiments.yml

my_first_experiment:

alternatives:
- A
- B
my_second_experiment:
alternatives:
- name: A
percent: 60
- name: B
percent: 40

abtest_second = ab_test(:my_second_experiment)

...

if abtest_second == 'A'
# 処理させたい内容を記載
end

これで、60%の人がAパターンになる出し分けが出来ます。

finishedを設定して、コンバージョンレートなどが見れるDashboardもあります。


■ ユーザー権限

cancan(進化系cancancan)が有名ドコロとしてありましたが、

開発が止まってしまっているのと、Punditのほうが柔軟性が高いので、こちらを。

認可ルールの記載場所は、一つのファイルにまとめるのではなく

コントローラ毎・リソース毎のように、柔軟に作成できます。

generateタスクも用意されています。

例)


app/controllers/application_controller.rb

class ApplicationController < ActionController::Base

include Pundit # <= インクルードしておく

protect_from_forgery
end


Punditにはauthorizeというメソッドが用意されており、


app/controllers/users_controller.rb

class UsersController < ApplicationController

before_action :pundit_auth

...

private
def pundit_auth
authorize User.new
end



app/model/user.rb

class User < ActiveRecord::Base

def self.admin?
...
end
end


app/policies/user_policy.rb

class UserPolicy < ApplicationPolicy

def update?
user.admin?
end
...

これでUsersController#updateが実行された際にcurrent_user.admin

falseだった際、NotAuthorizedErrorという例外が発生します。

参考:http://magazine.rubyist.net/?0047-IntroductionToPundit

比較として参考までに、

シェアはまだcancanのほうが高いですが、今後はpunditの方が伸びそうですね。

rails_authorization.png

cancan_pundit_cancancan.png


■ メンテナンス

メンテナンス画面を簡単に作成出来ます。

Railsのディレクトリに tmp/maintance.yml を置くと、設定したメンテナンス画面が表示され、サービスをメンテナンス中に出来てしまいます。

メンテナンス時に除外するIPアドレス、URLの指定も簡単です。

Capistranoとの連携も。

参考:http://morizyun.github.io/blog/turnout-maintenance-rails/


■ 検索機能

シノニム設定は出来ないですが、お手軽に検索のsqlが組み立てられます。


■ デバッグ関連

王道。便利。

better_errors使うなら、binding_of_callerも一緒に入れましょう。エラー画面でirbが利用出来るようになります。

pryを起動しているコンソールに戻るのが面倒な方にオススメです。

better_errors.gif


■ テスト関連

Fixtureがありますが、DBにテストデータを入れずに値だけほしい時だって、ありますね。

そんな時に便利です。


■ UserAgentごにょごにょ

ユーザーエージェントから、OSとブラウザ名、バージョンなどを取り出せるため、

ログとかで結構活躍します。

例)

Woothee.parse("Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)")

# => {:name=>"Internet Explorer", :category=>:pc, :os=>"Windows 7", :version=>"8.0", :vendor=>"Microsoft", :os_version=>"NT 6.1"}


■ プレゼンテーション層追加

Draperは、Railsのプレゼンテーション層の役割を担うgemです。

可読性、保守性を向上できます。


  • ビューにif文が多くて見づらい

  • ビューのロジックをヘルパーに書いているがヘルパーの名前空間の衝突が怖い

な人にオススメです。

参考:http://morizyun.github.io/blog/draper-ruby-gem-code-clear/


■ 攻撃対応

世の中は脅威に満ちています。

これを使えば、特定のパスへのアクセスを簡単に制限できます。

例) by github

# Always allow requests from localhost

# (blacklist & throttles are skipped)
Rack::Attack.whitelist('allow from localhost') do |req|
# Requests are allowed if the return value is truthy
'127.0.0.1' == req.ip || '::1' == req.ip
end

Rack::Attack.blacklist('only allow from office') do |req|

req.path.match(%r{^/admin}) && (req.ip != OFFICE_IP_ADDRESS)
end

# Throttle login attempts for a given email parameter to 6 reqs/minute

# Return the email as a discriminator on POST /login requests
Rack::Attack.throttle('logins/email', :limit => 6, :period => 60.seconds) do |req|
req.params['email'] if req.path == '/login' && req.post?
end


gem 探しツール


Ruby Toolbox

皆さんご存知

https://www.ruby-toolbox.com/


Github Trending repositories

https://github.com/trending?l=ruby

gem only ではないですが、指標のひとつとして。


BestGems

http://bestgems.org/

ダウンロード数を集計してRankingで表示してくれます。

toolboxと違って、Dailyとかでも見れるので、最近急に人気になったgemを見つけられそうです。

 http://bestgems.org/featured

 


有名どころの Gemfile

https://github.com/gitlabhq/gitlabhq/blob/master/Gemfile

 

 

 

 

 

 

該当gemの開発頻度(最終commit日時とか)や、世の中のgemトレンドを見ながら、

快適な gem Lifeを ♡