小規模Rails開発でよく使うGem

## はじめに
最近小規模案件を回す事が増えたので、小規模案件でよく使うGemをここにまとめます。

## kaminari
殆どの人が使っていると思われるほど有名なページネーション用のGemです。

```rb
gem 'kaminari'
```

ページングを使うときに使うGemはこれ一択。
以下、使用方法。

```sh
$ rails g kaminari:config
```

でConfigファイルを作成。

```rb:config/initializers/kaminari_config.rb
Kaminari.configure do |config|
  config.default_per_page = 10
  # config.max_per_page = nil
  # config.window = 4
  # config.outer_window = 0
  # config.left = 0
  # config.right = 0
  # config.page_method_name = :page
  # config.param_name = :page
end
```

作るだけ作ってデフォルトのまま使う事も多々ある。
上記の例では1ページに10件のデータを表示している。

```sh
# 使用可能テンプレートを調べる。
# 「avaliable themes: bootstrap2, bootstrap3, bourbon, foundation, github, google, materialize, purecss, semantic_ui」こちらが使用可能テンプレート
$ rails g kaminari:views -h

# 使うのはいつもbootstrap
$ rails g kaminari:views bootstrap3
```

使用するテンプレートを作る。
`app/views/kaminari/`に出来上がるのでデザインセンスのある方はここをカスタマイズしてください。
僕はまず、カスタマイズをしない。
（なぜなら、管理画面でしか使わないから。）

```rb
@user = User.page(params[:page]).all
# 表示件数を変えるときには以下のように行う。（モデル毎に設定する事も可能）
@user = User.page(params[:page]).per(40).all
```

コントローラー側でデータを取得するときには上記のように取得します。

```erb
<%= paginate(@users) %>
<% @users.each { |user| %>
	ここに表示処理を書く。
<% } %>
```

## sucker_punch
小規模で遅延処理を行うときはこれが便利。
なぜなら`redis`や`RDS`に依存せずに別処理ができるから。
（無名だけど、小規模サイトでは重宝します。）

```rb
gem 'sucker_punch', '~> 1.0'
```

ActiveJobでも使用できるので、以下のように定義。

```rb
Rails.application.configure do
  config.active_job.queue_adapter = :sucker_punch
end
```

Jobは以下のように`app/job`に登録。

```rb:app/job/task_job.rb
class TaskJob
  include SuckerPunch::Job

  def perform(event)
    Log.new(event).track
    # 1秒後に実行したい場合
    after(1) {Log.new(event).track}
  end
end
```

あとは呼び出すだけ。

```rb
# 非同期呼び出し
TaskJob.new.async.perform(event)
# 同期呼び出し
TaskJob.new.perform(event)
```

同一プロセスで動くので、引数はなんでも渡せるところが特徴。
ただし、同一プロセス内のスレッドで動くのでプロセスのCPUを消費してしまうデメリットもある。

使い方は[こちら](https://github.com/brandonhilkert/sucker_punch)

P.S.
中規模以降は`sidekiq`などを使ったほうが無難。

## whenever
スケジューリングをしたい場合はこちら。
僕がわざわざ説明するほどではないくらい有名なGem。

```rb
gem 'whenever', :require => false
```

`Rake`や`Runner`、`シェル`と組み合わせて使います。

```sh
$ wheneverize .
```

スケジュールファイルを作成して、スケジュールを書き込みます。

```rb
require File.expand_path(File.dirname(__FILE__) + "/environment")
rails_env = ENV['RAILS_ENV'] || :development

set :environment, rails_env
set :output, 'log/cron.log'

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

言及しませんが`environment`毎にスケジュールを組む事も可能です。

```sh
# 設定の確認
$ bundle exec whenever 
$ bundle exec crontab -e
# cronにデータを反映
$ bundle exec whenever --update-crontab 
# cronからデータを削除
$ bundle exec whenever --clear-crontab
```

これでCronへの反映が可能です。

使うときは[公式サイト](https://github.com/javan/whenever)をみてから使うと良いです。
Capistranoにも対応してるので管理がとても楽にできます。

P.S.
`sidekiq`を使ってる場合は`sidetiq`を使ったほうが構成がシンプルになると思う。
（使った事はないけど）

## dotenv-rails
これはRails4では標準としても良いのではないだろうか？

```rb
gem 'dotenv-rails'
```

環境毎に定義したい値を以下のファイルに記載する。

```txt:RailsRoot/.env
# 本番パスワード
DATABASE_PASSWORD = "root"
# 本番用シークレット(rake secretと組み合わせて使う）
SECRET_KEY_BASE = "****"
```

このファイルを各サーバーに配置すれば、本番データベースの接続情報などを隠蔽できる。
Rails3までは`config/database.yml`を個別にアップしていたが、Rails4からはこの方法が推奨されている。

```yaml:config/secrets.yml
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
```

```yaml:config/database.yml
production:
  <<: *default
  password: <%= ENV['DATABASE_PASSWORD'] %>
```

Rails4からはこのように定義されている。

Capistranoでは[このように](http://qiita.com/syou007/items/9b8a2f4d1ff099c64fc5#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%B8%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%97%E3%81%9F%E3%81%84)アップすることができる。
`linked_files`の設定も忘れずに！

## aws-sdk
AWSのS3は切っても切れない関係。

```rb
gem 'aws-sdk'
```

[僕の記事](http://qiita.com/syou007/items/44d92104c71f845d31fc)にアクセスクラスを作ったので、よければ使ってください。
→環境に合わせてS3を使うか、ローカルに保存するかを変更することができます。

## unicorn
昔はPassengerをメインに使ってたけど、別プロセスで動作するUnicornのほうが管理が楽なので本番適用にはこちらを使ってます。

```rb
gem 'unicorn'
```

設定は[こちら](http://qiita.com/syou007/items/8d48f975303df50db8fc)を読んでもらえれば分かると思います。

## bcrypt
説明不要かと・・・
Railsを使っててこのGemを使ったことがない人はいないはず・・・

```rb
gem 'bcrypt', '~> 3.1.7'
```

## rails_autolink
地味に便利・・・。

```rb
gem 'rails_autolink'
```

URLやメールなどに自動的にリンクを張りたいときに使います。

```rb
<%= auto_link @text %>
```

## quiet_assets
どうでも良いけど、重要なGem（笑）

```rb
group :development, :test do
  gem 'quiet_assets'
end
```

ローカルで開発をしていると`assets`への`get`がログに出てうるさいので消してくれる。

## activerecord-import
小規模ではあまり使わないけど、まれに使うので記述。

```rb
gem 'activerecord-import'
```

大量のデータをDBへ`insert`するときに使えます。

```rb
User.import data_list, on_duplicate_key_update: [:email], validate: false
```

`on_duplicate_key_update`を指定すれば、同一キーの場合はアップデートしてくれます。
`validate`をtrueにしたことはないけど、したら毎回`valid?`が呼ばれるのだろうか・・・？

P.S.
MySQLでしか使ったことがないので、ほかのRDSの場合は使う前に調査が必要。

## rest-client
あんまり使わないけど、、、RESTサーバーに対してリクエストを送るときには重宝します。

```rb
gem "rest-client", ">= 1.7.3"
```

使い方は割愛。

## rubyzip
地味に使います。zipファイルを圧縮したり、解凍したり。

```rb
gem 'rubyzip'
```

通常の使い方は割愛。

```rb
require "zip"
Zip::File.open_buffer(response.body) do |zf|
  zf.each do |entry|
    # ファイル名を取得する場合
    # p entry.name

    # ファイルの中身を返却します。
    filse << entry.get_input_stream.read # ファイルの中身
  end
end
```

HTTPリクエストの結果データがzipだった場合は上記のように取得できます。
このコードを知るまで僕は一度ファイルに保存してた・・・

## まとめ
僕が使ってるGemなので偏りがありますが、新しいプロジェクトを作る際にお役に立てれば幸いです。

あと`imagemagick`も使いますが、僕はRubyにコマンドを叩かせてしまいますので上記からは除外しました。（`CarrierWave`は未経験・・・。でも、同じことを`imagemagick`で頑張ったことはある。）