ウェブサービスを作っています。

Trigram という gem を作りました

2 つの文字列の類似度を計算する Trigram という gem を作りました。

https://github.com/milk1000cc/trigram

Trigram.compare 'he is genius', 'he is genius'  # => 1
Trigram.compare 'he is genius', 'he is very genius'  # => 0.5625
Trigram.compare 'he is genius', 'she is cute'  # => 0.26666666666666666
Trigram.compare 'he is genius', 'I can fly'  # => 0

文字列を 3 文字ずつに分割して、重複率を出す感じです。

以下の記事を読んでもらうと、よくわかると思います。

livedoor Techブログ : String::Trigram でテキストの類似度を測る

最近は PONPON の作り直しをしていて、似ているクーポンをまとめる処理などで使っています。

acts_as_digested_on という gem も更新しているので、よかったらご利用ください。

RSpec + VCR で HTTP テストデータを簡単に作成する

HTTP リクエストをスタブ化する WebMock というライブラリがあります。

これは便利なのですが、リクエストの数が増えてくると、テストデータの管理が大変な場合があります。

VCR を使うと、自動でテストデータを作成してくれて便利です。

参考: VCRを使うとRSpecのwebmockの作成が超絶楽になった! - 酒と泪とRubyとRailsと

ここでは、参考記事に載っていない、RSpecメタデータで記述する方法を紹介します。

Gemfile

group :test do
  gem 'webmock'
  gem 'vcr'
end

spec/spec_helper.rb

RSpec.configure do |config|
  ...
end

VCR.configure do |c|
  c.cassette_library_dir = 'spec/cassettes'
  c.hook_into :webmock
  c.configure_rspec_metadata!
end

spec/foo_api_spec.rb

describe 'foo api', vcr: { cassette_name: 'foo_api' } do
  it 'gets a respose from foo api' do
    response = call_foo_api(foo_api_url)
    expect(response.first).to eq 'hello world'
  end
end

これで、1 回目のみ実際のアクセスが行われ、spec/cassettes/foo_api.yml にレスポンスが保存されます。

2 回目からは spec/cassettes/foo_api.yml のデータが使用され、実際のアクセスは行われません。

参考: Usage with RSpec metadata - Test frameworks - Vcr - VCR - Relish

CarrierWave で Amazon S3 にアップロードする

という前提です。 CarrierWave のバージョンは 0.10.0 です。

Gemfile

gem 'carrierwave'
gem 'fog'
gem 'dotenv-rails'

config/initializers/carrierwave.rb

CarrierWave.configure do |config|
  if Rails.env.production?
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: ENV['S3_ACCESS_KEY_ID'],
      aws_secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
      region: ENV['S3_REGION'],
      path_style: true,
    }
    config.fog_directory = ENV['S3_BUCKET_NAME']
    config.storage :fog
    config.asset_host = ENV['S3_ASSET_HOST']
  else
    config.storage :file
  end
end

.env

S3_ACCESS_KEY_ID=XXX
S3_SECRET_ACCESS_KEY=XXX
S3_REGION=ap-northeast-1
S3_BUCKET_NAME=img.example.com
S3_ASSET_HOST=http://img.example.com

登録後からログインしたままにする Devise の設定

Devise (v3.2.2) で会員登録した後、ブラウザを閉じるとログアウト状態になってしまいます。

これを回避し、会員登録の直後から、常にログインしたままとする方法を考えてみました。

app/controllers/users/registrations_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController
  def create
    super { |resource| resource.remember_me = true }
  end
end

Devise::RegistrationsController#create は、ブロックを渡すと処理してくれるのでこのようにします。

パスワードリセット後もログイン状態を維持するには、app/controllers/users/passwords_controller.rb に同様の処理を書きます。

class Users::PasswordsController < Devise::PasswordsController
  def update
    super { |resource| resource.remember_me = true }
  end
end

あとは config/routes.rb で、これらのコントローラを参照するようにすれば OK です。

devise_for(:users,
    controllers: {
      registrations: 'users/registrations',
      passwords: 'users/passwords'
    })

ログイン状態の有効期限を延ばす設定

このようにして毎日アクセスしていても、ある日突然ログアウトしていることがあります。

これを防ぐには、config/initializers/devise.rb で以下の設定をします。

config.extend_remember_period = true

これで毎日アクセスするような場合は、勝手にログアウトされることがなくなります。

さくらのVPSでカスタムOSインストールができないとき

さくらの VPS で、カスタム OS インストールをしようとしたのですが、VNC コンソールが立ち上がりませんでした。

原因は、Java のセキュリティ設定でした。

以下、Mac の場合ですが、Windows などでも同様の手順で対処できると思います。

対処方法

  1. 最新版の Java をインストールする http://java.com/

  2. システム環境設定の Java から「Javaコントロール・パネル」を開く

  3. 「セキュリティ」タブの「例外サイト・リスト」に https://secure.sakura.ad.jp/ を追加

  4. FirefoxSafari で、VPS コントロールパネルを開く。Mac Chrome は、Java7 に対応していないようです

Chef Solo 基本操作まとめ

初回の操作

必要ならば Virtualbox, Vagrant をインストールしておく。

gem インストール

gem install chef  # chef-solo, knife コマンドが入る
knife configure  # 空欄で OK
gem install knife-solo  # knife solo が使えるようになる

レポジトリ作成

cd ~/dev/private
knife solo init chef-repo
cd ~/dev/private/chef-repo
git init
git commit -m ‘initial commit’

サーバごとの操作

サーバ名を melody とする。

サーバ準備

cd ~/dev/private/chef-repo
knife solo prepare melody
git add nodes/melody.json
git commit -m ‘add node json file’

クックブック作成

cd ~/dev/private/chef-repo
knife cookbook create nginx -o site-cookbooks
vi site-cookbooks/nginx/recipes/default.rb
vi nodes/melody.json

Chef Solo 実行

knife solo cook melody
git add site-cookbooks/nginx
git commit -m ‘Add nginx recipe’

サーバ上の不要ファイル削除

knife solo clean melody

参考

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code