2016年5月31日火曜日

【Rails4.2.6】omniauth-google-oauth2でJWT::InvalidIatError

  • 公開日:2016年05月31日

記事概要

Railsでomniauth-google-oauth2を使った時に、JWT::InvalidIatErrorが発生しました。
このエラーの修正方法を記述した記事です。

環境

  • rbenv
  • bundler
  • rails 4.2.6
  • ruby 2.3.0

omniauth-google-oauth2

omniauth-google-oauth2は、Railsのgoogleログインの認証ライブラリです。
少ないコードでgoogleログインの認証処理が実装できます。

エラー

googleログイン認証のコールバック時に、JWT::InvalidIatErrorが発生しました。 原因は、OSの時間のずれです。
この時、セッショントークンの生成に問題が発生します。

本番環境では、まず発生しないエラーです。vagrantやdockerを使用していると発生する可能性があります。

修正方法

OmniAuth::Builderに:skip_jwt => trueを設定します。

{project_folder}/config/initializers/omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", {:skip_jwt => true }
end

ファイル変更後に、サーバーを再起動して再度ログインします。
同じ失敗をする場合は、古いセッションを削除してから試してください。

まとめ

Railsのomniauth-google-oauth2は、deviseと連携した記事がほとんどなので、単体で使うとエラーの調査に苦戦します。
twitterやfacebookのログインよりも安定感があるので、皆さんにももっと積極的に利用して欲しいです。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

参考記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月28日土曜日

【Golang】初めてのGolang 本番への導入を検証する その3 json

  • 公開日:2016年05月28日

記事概要

APIサービスをRailsでなく、GoLangで作ることを検証しました。
その検証内容をまとめた記事です。

環境

  • Centos6.5
  • Go 1.6.2
  • Nginx 1.8.1

初めに

スマートフォンアプリ用のAPIサービスをRailsでなく、GoLangで作るかどうかを検証しました。
以下が、最低限必要な検証項目です。

今回は、言語仕様や文法の基礎的なことは、学習しません。
長く使えそうな言語ならやっていきます。
ダメな場合の候補は、Rails, Spring, djangoです。

前回の記事で「nginx経由でgolangサーバーにアクセス」したので、今回はgolangでjsonを扱います。

golangでjson

ここでは、以下のjsonを返すAPIを作成します。

{project_folder}/src/sample.go
{
  "last_updated_at": "yyyy-MM-dd HH:mm:ss",
  "master": [{
      "id": 1,
      "name": "news",
      "summmey": "news contents",
      "category": "economic"
    }, {
      "id": 2,
      "name": "sports",
      "summmey": "news contents",
      "category": "baseball"
    }
  ]
}

サンプルなので、スマホアプリによくある典型的なjsonにしました。

jsonの処理はjsonパッケージを使います。

Struct

Golangでjsonを使う場合は、structの知識が必要になります。

使い方は、C言語系のstructとほぼ同じです。JavaやRubyのクラスともほぼ同じです。
typeはinterfaceとしても宣言できますが、この記事では必要ないので説明しません。

サーバーの変更

Golangのサーバーの処理でjsonを返却するには、以下のコードを追加します。

{project_folder}/src/sample.go

res.Header().Set("Content-Type", "application/json")

これでjsonが返却可能になります。

jsonの実装

Golangのhandler関数でjsonの処理を以下のように追加します。

{project_folder}/src/sample.go
package main

import (
  "fmt"
  "net"
  "net/http"
  "net/http/fcgi"
  "encoding/json"
)

type Sample struct {
    Master []Master `json:"master"`
    LastUpdateAt string `json:"last_updated_at"`
}

type Master struct {
  Id string `json:"id"`
  Name string `json:"name"`
  Summmey string `json:"summmey"`
  Category string `json:"category"`
}

func viewHandler(res http.ResponseWriter, req *http.Request) {
  res.Header().Set("Content-Type", "application/json")

  master1 := Master {"1","master1","sum1","cat1"}
  master2 := Master {"2","master2","sum2","cat2"}

  // 配列
  masters := []Master{master1, master2}

  sample1 := Sample{Master: masters, LastUpdateAt: "2016/07/01 20:11:11"}
  resJson, _ := json.Marshal(sample1)
  fmt.Fprintf(res, string(resJson))
}

func main() {
  l, err := net.Listen("tcp", "127.0.0.1:8190")
    if err != nil {
        return
    }
    http.HandleFunc("/", viewHandler)
    fcgi.Serve(l, nil)
}

コードの説明をします。

1. Sample struct


type Sample struct {
    Master []Master `json:"master"`
    LastUpdateAt string `json:"last_updated_at"`
}

json全体の

{ "last_updated_at": "yyyy-MM-dd HH:mm:ss", "master": [] }

を表現する構造体です。

2. Master struct


type Master struct {
  Id string `json:"id"`
  Name string `json:"name"`
  Summmey string `json:"summmey"`
  Category string `json:"category"`
}

jsonの

{ "id": 1, "name": "news", "summmey": "news contents", "category": "economic" }

を表現する構造体です。

3. Json出力


  master1 := Master {"1","master1","sum1","cat1"}
  master2 := Master {"2","master2","sum2","cat2"}

  // 配列
  masters := []Master{master1, master2}

  sample1 := Sample{Master: masters, LastUpdateAt: "2016/07/01 20:11:11"}
  resJson, _ := json.Marshal(sample1)

Masterの配列データを作成し、Sampleの構造体を作成します。json.Marshalという関数を使うことで、jsonデータを取得できます。

実行

terminal

go run sample.go

ブラウザでhttp://localhost/golangにアクセスします。

画面が表示されました。

まとめ

GoLangでjsonを扱うのは、色々な方法が用意されています。
この記事で記述した内容は、java, php, ruby, python等のコーディングに慣れている人にはわかりやすいのではないでしょうか。

まずは、他言語風の実装に慣れてから、リファクタリングで徐々にGoLangに適したコーディングスタイルにすれば良いのではないでしょうか。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

関連記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月27日金曜日

【Golang】初めてのGolang 本番への導入を検証する その2 Nginx連携

  • 公開日:2016年05月27日

記事概要

APIサービスをRailsでなく、GoLangで作ることを検証しました。
その検証内容をまとめた記事です。

環境

  • Centos6.5
  • Go 1.6.2
  • Nginx 1.8.1

初めに

スマートフォンアプリ用のAPIサービスをRailsでなく、GoLangで作るかどうかを検証しました。
以下が、最低限必要な検証項目です。

  • centos6.5にgolangをインストール(済)
  • golangでサーバーを動かす。
  • nginx経由でgolangサーバーにアクセスする。
  • golangでAPIを叩いてjsonを返却する
  • mysqlに接続する。
  • ログを吐き出す。

今回は、言語仕様や文法の基礎的なことは、学習しません。
長く使えそうな言語ならやっていきます。
ダメな場合の候補は、Rails, Spring, djangoです。

前回の記事で「centos6.5にgolangをインストール」したので、今回はgolangでサーバーを動かし、nginx経由でgolangサーバーにアクセスします。

golangをサーバーで動かす

Go言語をWebサーバーで動かすには、2種類の方法があります。

  • GoでWebサーバーを動かす
  • ApacheやNginxなどのWebサーバーで、FastCGIとしてGoを動かす

今回は、後者の「Webサーバーで、FastCGIとしてGoを動かす」方法を選択します。
php, ruby, python等のWEBサーバーと同じような仕組みにします。

GolangのWebサーバー

まずは、GolangでWebサーバーを動かします。
以下のようにWebサーバーのコードを実装します。

{project_folder}/src/sample.go
package main

import (
  "fmt"
  "net/http"
)

func viewHandler(res http.ResponseWriter, req *http.Request) {
  fmt.Fprintf(res, "<h1>%s</h1><div>%s</div>", "title", "aaaaaaaa")
}

func main() {
  http.HandleFunc("/", viewHandler)
  http.ListenAndServe(":8190", nil)
}

Golangを実行します。

terminal

go run sample.go

ブラウザでhttp://localhost:8190/にアクセスします。

画面が表示されました。

Nginx経由でGolangサーバーにアクセス

次にNginx経由で、GolangのWebサーバーにアクセスします。

まずはNginxのアプリの設定を変更します。

/etc/nginx/conf.d/app.conf

    location / {
        try_files $uri $uri.html $uri/index.html @rails-unicorn;
    }

    location /golang {
        fastcgi_pass 127.0.0.1:8190;
        include fastcgi.conf;
    }

上記の設定をすると、domain/golangのアドレスが与えられた場合、Nginxは127.0.0.1:8190にFastCGIでリクエストします。

FastCGIは、一度起動したプログラムを一定期間、メモリ上に展開しておく仕組みです。
このサイトの説明がわかりやすいです。

Go側のコードもFastCGIを使うように修正します。GoLangには、fcgiパッケージが用意されているので、これを利用します。

{project_folder}/src/sample.go

package main

import (
  "fmt"
  "net"
  "net/http"
  "net/http/fcgi"
)

func viewHandler(res http.ResponseWriter, req *http.Request) {
  fmt.Fprintf(res, "<h1>%s</h1><div>%s</div>", "hello", "fastCGI ")
}

func main() {
  l, err := net.Listen("tcp", "127.0.0.1:8190")
    if err != nil {
        return
    }
    http.HandleFunc("/", viewHandler)
    fcgi.Serve(l, nil)
}

Nginxを再起動し、Goを実行します。

terminal

sudo service nginx restart

go run sample.go

ブラウザでhttp://localhost/golangにアクセスします。

画面が表示されました。

UNIX socketを使う場合も同様にnetパッケージを利用します。

まとめ

GoLangでNginxの連携は、シンプルに実装可能です。
php, ruby, python等で連携の経験があるなら、特にはまることはないでしょう。

スクリプト言語の経験がある人には、とてもとっつきやすい仕組みだと思います。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

関連記事

参考記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月26日木曜日

【Golang】初めてのGolang 本番への導入を検証する その1 インストール

  • 公開日:2016年05月26日
  • 最終更新日:2016年05月28日

記事概要

APIサービスをRailsでなく、GoLangで作ることを検証しました。
その検証内容をまとめた記事です。

環境

  • Centos6.5
  • Go 1.6.2
  • Nginx 1.8.1

はじめに

スマートフォンアプリ用のAPIサービスをRailsでなく、GoLangで作るかどうかを検証しました。
以下が、検証項目です。

  • Centos6.5にgolangをインストールする。
  • golangでサーバーを動かす。
  • nginx経由でgolangサーバーにアクセスする。
  • golangで作成したAPIを叩いてjsonを返却する
  • mysqlに接続する。
  • ログを吐き出す。

今回は、言語仕様や文法の基礎的なことは学習しないで、行き当たりバッタリで進めていきます。
調査しながらでもコードがなんとか書けるというのも、言語の重要な選定要素と思うからです。

直感的に長く使えそう、息の長そうと思える言語なら、今後基礎的な学習もやっていきます。
ダメな場合は、Rails, Spring, djangoで作ろうと思います。

インストール

GoLangをcentos6.5にインストールします。
現在の最新バージョン1.6.2を使います。

terminal

// ダウンロード
wget https://storage.googleapis.com/golang/go1.6.2.linux-amd64.tar.gz

// rootになる
su - 

// /usr/localフィレクトリに解凍
// -C, --directory  ディレクトリ名 指定したディレクトリに移動してから動作を始める
tar -C /usr/local -xzf go1.6.2.linux-amd64.tar.gz

// 環境変数の設定フォルダ
cd /etc/profile.d/

// goの環境変数を読み込むshを作成
touch go.sh

vi go.sh

/etc/profile.d/配下のgo.shは、サーバーログイン時に呼び出されるシェルです。(正しくは、ログイン時にシェルで*.shとして、全てのシェルが呼び出される。)
このgo.shファイルで環境変数を設定します。

/etc/profile.d/go.sh

export PATH=$PATH:/usr/local/go/bin

保存したら、一度サーバーからログアウトします。
再度サーバーにログインして、golangの設定をチェックします。

terminal

// version確認
[vagrant@vagrant-centos65 profile.d]$ go version
go version go1.6.2 linux/amd64

正常に設定が完了しました。

まとめ

GoLangのインストールは非常にシンプルです。
chefを使って管理する場合は、supermarketのレシピがcentos6.5に未対応なので、自分でレシピを記述する必要があります。

個人的な意見では、ubuntuならchefを使って、centosなら手動でinstallすれば良いと思います。

dockerや、他のミドルウェアの開発を見ると、今後の開発ではcentosよりubuntuを使うべきですね。centosはエンタープライズ用になっていきそうな流れです。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

関連記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月23日月曜日

【Rails4.2.6】Railsエンジンの懸念点と解決方法

  • 公開日:2016年05月23日

記事概要

Railsのエンジン利用時の、懸念点と解決方法をまとめた記事です。

環境

  • rbenv
  • bundler
  • rails 4.2.6
  • ruby 2.3.1

他言語化

Railsエンジンを他言語化する方法は、通常のアプリケーションと同じです。
他言語化は、こちらの記事通りに実装します。

一点異なるのは、設定ファイルをconfig/application.rbでなく、lib/xxxx_engine/engine.rbに記述することです。

{project_folder}/lib/xxxx_engine/engine.rb

module XxxxEngine
  class Engine < ::Rails::Engine
    isolate_namespace XxxxEngine

    config.i18n.default_locale = :ja
    config.i18n.available_locales = [:en, :ja]

  end
end

capistrano3を使ったdeploy

capistrano3でリリースをしている人は、自動deployができるかを心配するかもしれません。

しかし、その心配は杞憂です。
Gemfileに名称とurlを記述すれば、一般公開されているgemと同じようにインストールも更新もできます。 リポジトリは、プライベートリポジトリでも問題ありません。

{project_folder}/Gemfile

# User my_engine
gem 'my_engine', :git => 'git@git:user/my-engine.git'

また、railsエンジンのtableは、用意されたコマンドでメインアプリにmigrateファイルをコピーできます。 なので、通常のdeploy手順でアプリのリリースが可能です。

ライブラリのバージョン違い

例として、フック先のメインのrailsアプリがrails4.1.3で、サブプロジェクトのrailsエンジンがrails4.2.6でも正常に動作します。
もちろんこの時、メインのrailsアプリはバージョン4.1.3のアプリとして動作します。

とはいえ、あまり気持ちの良いものではないので、理由がない限りバージョンは合わせましょう。
常にrubyとrailsは最新のバージョンを保つべきです。

まとめ

Railsのエンジン機能は、スタートアップなどで、高速に色々な機能実装をしていく場合に役立ちます。
作成したエンジンは他のプロジェクトでも使いまわせます。
エンジンプロジェクトの資産がたまれば、さらに多くのアプリを高速に量産できるようになります。

うまくエンジンを利用して、疎結合な優れたアプリを量産してください。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

参考記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月21日土曜日

【Rails4.2.6】Railsエンジンをアプリケーションで利用する

  • 公開日:2016年05月21日

記事概要

Railsのエンジン機能を、アプリケーションで利用する方法をまとめた記事です。

環境

  • rbenv
  • bundler
  • rails 4.2.6
  • ruby 2.3.0

エンジンプロジェクトの設定

作成したRailsエンジンプロジェクトをアプリケーションにフックするには、Gemfileにエンジン名URL(パス)を記述します。
ここでは、user_engineという名称のユーザーRailsエンジンがあると仮定して話を進めます。

{project_folder}/Gemfile

gem 'user_engine', :git => 'git@url.git'

gitのurlはプライベートリポジトリurlでも問題ありません。

インストールは、他のgemと同じようにbundleコマンドでインストールします。

terminal

cd {project_folder}/

bundle install

エンジンプロジェクトのマウント

gemをインストールしたら、アプリケーションにエンジンをマウントします。

{project_folder}/config/routes.rb

mount UserEngine::Engine, at: "/user"

アプリケーションのroutes.rbファイルにこの行を記述することで、エンジンがアプリケーションの/userパスにマウントされます。

テーブル作成

エンジンプロジェクトのデータベースがアプリケーションに必要な場合は、エンジンのmigrationをアプリケーションにコピーします。

以下のコマンドを利用します。

terminal

cd {project_folder}/

bundle exec rake user_engine:install:migrations

Copied migration 20160520033732_create_tests.user_engine.rb from user_engine

コマンド実行後に{project_folder}/db/migrate/フォルダにエンジンからコピーしたマイグレーションが追加されていることを確認します。
存在を確認したら、通常のmigrateコマンドを叩きます。

terminal

bundle exec rake db:migrate RAILS_ENV=development

tableが作成されたら準備完了です。

アプリ立ち上げ

アプリケーションを立ち上げます。

terminal

cd {project_folder}/

// サーバー立ち上げ
rbenv exec bundle exec rails s -b 0.0.0.0

成功した場合はサーバーが立ち上げり、プロジェクトでフックしたエンジンの機能が利用できるようになっています。

まとめ

Railsのエンジン機能は、スタートアップなどで、高速に色々な機能実装をしていく場合に役立ちます。
作成したエンジンは他のプロジェクトでも使いまわせます。
エンジンプロジェクトの資産がたまれば、さらに多くのアプリを高速に量産できるようになります。

うまくエンジンを利用して、疎結合な優れたアプリを量産してください。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

参考記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月20日金曜日

【Rails4.2.6】capistrano-maintenance capistrano/tasks/maintenance.rake:1:in undefined method `namespace' for main:Object (NoMethodError)

  • 公開日:2016年05月20日

記事概要

capistrano-maintenanceのGemインストール後、rbenv exec bundle exec rails s -b 0.0.0.0でサーバーの起動に失敗しました。
この記事は、capistrano-maintenanceのNoMethodErrorエラーの修正方法について記述しています。

環境

  • rbenv
  • bundler
  • rails 4.2.6
  • ruby 2.3.0
  • capistrano 3.2.1
  • capistrano-maintenance
  • Nginx 1.8.1

capistrano-maintenance

capistrano-maintenanceは、capistrano3を使って、capコマンドでメンテナンス画面の表示非表示を切り替えることのできるライブラリです。

エラーの発生

capistrano-maintenanceをbundle installし、検証環境と本番環境(unicorn and Nginx)の動作確認後に、development環境でエラーが発生しました。
このエラーは、unicornサーバーでは発生しません

エラーの修正

以下のようにGemfileを修正します。

修正前

{project_folder}/Gemfile

group :development do
  gem 'capistrano-maintenance', '~> 1.0'
end

修正後

{project_folder}/Gemfile

group :development do
  gem 'capistrano-maintenance', '~> 1.0', require: false
end

require: falseを追加することで、rbenv exec bundle exec rails s -b 0.0.0.0でサーバーを立ち上げられるようになります。

まとめ

メンテナンス画面の切り替えは、手動では面倒な作業です。間違えも起きやすいです。
とても便利なツールなので、capistrano3でdeployをおこなっている開発者は、capistrano-maintenanceを利用してみてください。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

参考記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月19日木曜日

【Rails4.2.6】capistrano3でメンテナンス画面を表示する

  • 公開日:2016年05月19日
  • 最終更新日:2016年05月26日

記事概要

capistrano3のアプリビルド時にメンテナンス画面を表示する方法を記載した記事です。

環境

  • rbenv
  • bundler
  • rails 4.2.6
  • ruby 2.3.0
  • capistrano 3.2.1
  • Nginx 1.8.1

ビルド時のメンテナンス画面

WEBアプリのデプロイをする時に、一時的にメンテナンス画面を出したい時があります。
例えば、databaseの変更が必要でdb:migrateをする時や、大きな追加機能や修正がある場合です。

capistrano3には、メンテナンス画面の表示非表示を切り替える機能があります。
それを使ってdeploy時に簡単にメンテナンス画面を表示できます。

capistrano-maintenanceのインストール

capistrano3でメンテナンス画面の非表示をするには、capistrano-maintenanceというGemを利用します。

以下のようにGemfileに記述します。

{project_folder}/Gemfile

group :development do
  gem 'capistrano-maintenance', '~> 1.0'
end

bundleを使ってインストールします。

terminal

cd {project_folder}

bundle

Installing capistrano-maintenance 1.0.0

rails側の準備は以上です。

Nginxの修正

続いてNginxの修正です。

capistrano-maintenanceは、capコマンドを叩くと、


{project_folder}/shared/public/system/maintenance.html

というファイルの生成と削除がおこなえるライブラリです。
つまり、メンテナンス画面ファイルの作成と削除の操作をcapコマンドでコントロールするライブラリです。

なので、Nginxのconfファイルに、メンテナンス画面ファイルの有無の実装が必要です。

以下のように記載します。

/etc/nginx/conf.f/project.conf

    error_page 503 @503;

    # Return a 503 error if the maintenance page exists.
    if (-f {project_folder}/shared/public/system/maintenance.html) {
      return 503;
    }

    location @503 {
      # Serve static assets if found.
      if (-f $request_filename) {
        break;
      }

      # Set root to the shared directory.
      root {project_folder}/shared/public;
      rewrite ^(.*)$ /system/maintenance.html break;
    }

実装ポイントは以下となります。

ファイルの存在チェック

Nginxでは、-fはファイルが存在するかを示すオプションです。なので、


-f {project_folder}/shared/public/system/maintenance.html

は、maintenance.htmlが存在する場合にtrueを返します。

つまり、この記述で、maintenance.htmlの有無で閲覧ファイル先を切り替えています。

capistrano3の実行

では、実際に実行します。

capコマンドでメンテナンス画面を表示します。

terminal

bundle exec cap staging maintenance:enable REASON="hardware upgrade" UNTIL="12pm Central Time"

ブラウザには以下のような画面が表示されます。

メンテナンス画面

capコマンドでメンテナンス画面を削除します。

terminal

bundle exec cap staging maintenance:disable

ブラウザでメンテナンス画面が非表示になることを確認してください。

本番のdeploy作業では、メンテナンスコマンドの後に、bundle exec cap production deploy等のコマンドを実行することになります。

まとめ

メンテナンス画面の切り替えは、手動だと意外と面倒な作業です。間違えも起きやすいです。
とても便利なツールなので、capistrano3でdeployをおこなっている開発者は、capistrano-maintenanceを利用してみてください。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

参考記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月17日火曜日

【Rails4.2.5】Mysql2::Error: Access denied for user

  • 公開日:2016年05月17日

記事概要

rake db:create失敗時に発生するMysql2::Error: Access denied for userの修正方法

環境

  • rbenv
  • bundler
  • rails 4.2.5
  • ruby 2.3.0

はじめに

Mysql2::Error: Access denied for userは、Railsでプロジェクトを開発するたびに、毎回やらかしてしまうエラーです。
なので、修正方法を記載しておきます。

Mysql2::Error: Access denied for user

rake db:createの実行時によく発生するエラーです。
原因は、databaseに既にユーザーが存在しているからです。

修正方法

mysqlのユーザー情報を調査して、ユーザーが存在すれば削除、もしくはdatabaseを作成するユーザーを新規追加します。

ユーザー情報は、以下のコマンドで調査します。

mysql

mysql> SELECT USER FROM mysql.user;

既にユーザーが存在している場合は、ユーザーを削除してからrake db:createを実行します。
もう一つの方法として、database.ymlのusernameにmysql.userに存在しないユーザー名を指定することで、対応できます。

{project_folder}/config/database.yml

staging:
  <<: *default
  username: db_staging ← mysql.userに存在しないユーザー名
  password: db_staging
  database: db_staging

個人的には、後者の対応方法をお勧めします。

まとめ

Railsのdb:createやdb:migrateは癖の強いコマンドです。
プロジェクトではドキュメントを残しておくことをお勧めします。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月16日月曜日

【Rails4.2.5】RailsエンジンでRspecを利用する

  • 公開日:2016年05月16日
  • 最終更新日:2016年05月20日

記事概要

RailsエンジンでRspecを利用する方法をまとめた記事です。

環境

  • rbenv
  • bundler
  • rails 4.2.5
  • ruby 2.3.0

Rspecを利用するエンジンプロジェクトの作成

RailsエンジンでRspecを利用する時は、以下のコマンドでサブプロジェクトを作成します。

terminal

// rspecを使う場合
bundle exec rails plugin new user_engine --mountable -T --dummy-path=spec/dummy

--dummy-pathオプションで、spec/dummyを指定します。指定しない場合は、test/dummyになります。
すでに作成済みのサブプロジェクトの場合は、フォルダ名を


test/dummy → spec/dummy

に変更します。

Rspecのインストール

specフォルダが作成できたら、Rspecをインストールします。
必要なGemをGemfileに記述します。

{project_folder}/Gemfile

group :test do
  gem 'rspec-rails'
  gem "factory_girl_rails", ">= 4.1.0"
  gem 'database_cleaner', ['>= 1.2', '!= 1.4.0', '!= 1.5.0']
  gem 'rubocop', require: false
end

bundlerでGemをインストールします。

terminal

cd /workspace/sub_project

bundle install

サブプロジェクトにRspecをインストールします。

terminal

cd /workspace/sub_project

rbenv exec bundle exec rails generate rspec:install

      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb

specの動作に必要なspecファイルが作成されます。

設定ファイル編集

インストールしたspecファイルに、specの動作に必要な設定をします。
rails_helper.rbとengine.rbを編集します。

rails_helper.rb編集

まずrails_helper.rbを編集します。

{project_folder}/spec/rails_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path("../dummy/config/environment", __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'factory_girl_rails'

Dir["#{File.dirname(__FILE__)}/spec/factories/**/*.rb"].each { |f| require f }

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.clean_with(:truncation)
  end

  # every time
  config.before(:each) do
    DatabaseCleaner.start
  end

  # every time
  config.after(:each) do
    DatabaseCleaner.clean
  end

end

重要なポイントは以下となります。

environmentの設定

環境設定の読み込み位置を変更します。


../../config/environment → ../dummy/config/environment

factory_girl_railsの設定


require 'factory_girl_rails'

Dir["#{File.dirname(__FILE__)}/spec/factories/**/*.rb"].each { |f| require f }

factory_girlは、DBのテストが必要な場合には導入しておきましょう。

database_cleanerの設定


  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.clean_with(:truncation)
  end

  # every time
  config.before(:each) do
    DatabaseCleaner.start
  end

  # every time
  config.after(:each) do
    DatabaseCleaner.clean
  end

factory_girlを利用する場合は、database_cleanerも導入することをお勧めします。

engine.rb編集

次にengine.rbを編集します。

{project_folder}/lib/user_engine/engine.rb

module UserEngine
  class Engine < ::Rails::Engine
    isolate_namespace UserEngine

    config.generators do |g|
      g.test_framework :rspec, :fixture => false
      g.fixture_replacement :factory_girl, :dir => 'spec/factories'
    end

    initializer "model_core.factories", :after => "factory_girl.set_factory_paths" do
      FactoryGirl.definition_file_paths << File.expand_path('../../../spec/factories', __FILE__) if defined?(FactoryGirl)
    end
  end
end

lib/{engine_name}/engine.rbファイルは、Railsアプリケーションが標準で持つconfig/application.rbファイルと同一の機能を持ちます。
このファイルにもspecファイルの設定を記述します。

Rspecの実行

全ての設定を終えたらRspecの実行を行います。

terminal

cd /workspace/sub_project

bundle exec rspec spec

52 examples, 0 failures, 16 pending

成功しました。

まとめ

通常のRailsでRspecを利用している場合は、RailsエンジンでもRspecを使うことをお勧めします。
設定ファイル等のわずかな違いに、多少つまづくことがあるかもしれませんが、良い学習の機会と捉え、Rubyの力の底上げを図りましょう。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

参考記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年5月6日金曜日

【Rails4.2.5】Railsエンジンでサブプロジェクトを作成する

  • 公開日:2016年05月06日
  • 最終更新日:2016年05月09日

記事概要

Railsでエンジン機能を使ってサブプロジェクトを作成する方法をまとめた記事です。

環境

  • rbenv
  • bundler
  • rails 4.2.5
  • ruby 2.3.0

Railsエンジン

Railsエンジンは、ホストアプリケーションに機能を提供します。
例えば、ニュースを表示するWEBアプリに、管理画面やユーザー機能を追加する時に利用します。

エンジンとアプリケーションは、細かな違いを除けばほぼ同じです。
なので、エンジンはプラグインになることもでき、プラグインがエンジンになることもできます。

Railsエンジンの利点

Railsエンジンを使うと、アプリを小さく保つことができます。
これは素晴らしい利点です。

WEBアプリは継続的なアップデートが必要になります。Railsは優れたフレームワークで、高速な開発を可能にしますが、アップデートは、WEBアプリを肥大化させます。
肥大化したアプリの保守や新規機能の追加は大変です。ファイルの増大はファイルの容量を増加させ、バージョン管理の速度も遅くします。

しかし、Railsエンジンを使ってサブプロジェクトとして、アプリの機能を作成することで、コードの可読性、生産性、再利用性を大幅に向上させることができます。

有名なRailsエンジン

ログイン機能を提供するdeviseやEC機能を提供するSpreeなどが有名です。

エンジンプロジェクトの注意点

エンジンを作成するとき、エンジンプロジェクトは、メインプロジェクトとは別のフォルダに作成します。

terminal

cd workspace

ls -l

drwxr-xr-x   main_project

上記のように、メインプロジェクトが/workspace/main_projectのようなフォルダ構成になっている場合、メインプロジェクトのエンジンとわかるようにサブプロジェクトを作成すると良いでしょう。

terminal

cd /workspace

ls -l

drwxr-xr-x   main_project
drwxr-xr-x   sub_project

エンジン作成

では、実際にエンジンのサブプロジェクトを作成します。

terminal

cd /workspace

// mini testを使う場合
bundle exec rails plugin new user_engine --mountable

// rspecを使う場合
bundle exec rails plugin new user_engine --mountable -T --dummy-path=spec/dummy

上記のコマンドで、エンジンサブプロジェクトが作成されます。
rspecを使う場合は、spec/dummyにするのがポイントです。通常は、test/dummyになります。

DB作成

データベースが必要な場合は、通常のrailsアプリと同じように作成します。

terminal

cd /workspace/user_engine/

bundle exec rake db:create
bundle exec rake db:migrate RAILS_ENV=test
bundle exec rake db:migrate RAILS_ENV=development

準備は以上です。

アプリ立ち上げ

作成したエンジンを立ち上げます。

terminal

cd /workspace/user_engine/test/dummy

// rspecを使っている場合
cd /workspace/user_engine/spec/dummy

// サーバー立ち上げ
rbenv exec bundle exec rails s -b 0.0.0.0

test/dummy(specの場合はspec/dummy)配下でサーバー立ち上げコマンドを叩くことに注意してください。

成功した場合は、通常プロジェクトと同じようにブラウザにデフォルト画面が表示されます。

まとめ

Railsのエンジン機能は、スタートアップなどで、高速に色々な機能実装をしていく場合に役立ちます。
作成したエンジンは他のプロジェクトでも使いまわせます。
エンジンプロジェクトの資産がたまれば、さらに多くのアプリを高速に量産できるようになります。

うまくエンジンを利用して、疎結合な優れたアプリを量産してください。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)

参考記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加
Related Posts Plugin for WordPress, Blogger...