285
274

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

リクルートライフスタイルAdvent Calendar 2015

Day 19

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

Last updated at Posted at 2015-12-18

(リクルートライフスタイル 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
```
```rb:app/model/user.rb
class User < ActiveRecord::Base
    def self.admin?
    ...
    end
end
```
````rb: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](https://qiita-image-store.s3.amazonaws.com/0/15055/9b712ee3-1401-d9e6-1d82-b0723114e28d.png)

![cancan_pundit_cancancan.png](https://qiita-image-store.s3.amazonaws.com/0/15055/2e9769b8-5616-9138-23d9-74fb16abd0f0.png)



## ■ メンテナンス
- [turnout](https://github.com/biola/turnout)

メンテナンス画面を簡単に作成出来ます。
Railsのディレクトリに `tmp/maintance.yml` を置くと、設定したメンテナンス画面が表示され、サービスをメンテナンス中に出来てしまいます。
メンテナンス時に除外するIPアドレス、URLの指定も簡単です。

Capistranoとの連携も。
参考:http://morizyun.github.io/blog/turnout-maintenance-rails/


## ■ 検索機能

- [ransack](https://github.com/activerecord-hackery/ransack)

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



## ■ デバッグ関連

- [better_errors](https://github.com/charliesome/better_errors)
- [binding_of_caller](https://github.com/banister/binding_of_caller)

王道。便利。
`better_errors`使うなら、`binding_of_caller`も一緒に入れましょう。エラー画面でirbが利用出来るようになります。
pryを起動しているコンソールに戻るのが面倒な方にオススメです。

![better_errors.gif](https://qiita-image-store.s3.amazonaws.com/0/15055/98b970de-8ad8-af32-4adb-5c0173d8f648.gif)


## ■ テスト関連

- [factory_bot_rails](https://github.com/thoughtbot/factory_bot_rails)

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


## ■ UserAgentごにょごにょ
- [woothee](https://github.com/woothee/woothee)

ユーザーエージェントから、OSとブラウザ名、バージョンなどを取り出せるため、
ログとかで結構活躍します。

`例)`

```rb
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](https://github.com/drapergem/draper)

Draperは、Railsのプレゼンテーション層の役割を担うgemです。
可読性、保守性を向上できます。

- ビューにif文が多くて見づらい
- ビューのロジックをヘルパーに書いているがヘルパーの名前空間の衝突が怖い

な人にオススメです。


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

## ■ 攻撃対応
- [rack-attack](https://github.com/kickstarter/rack-attack)

世の中は脅威に満ちています。
これを使えば、特定のパスへのアクセスを簡単に制限できます。

`例)` by github

```rb
# 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
```
```rb
Rack::Attack.blacklist('only allow from office') do |req|
  req.path.match(%r{^/admin}) && (req.ip != OFFICE_IP_ADDRESS)
end
```
```rb
# 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 
 
285
274
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
285
274

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?