Help us understand the problem. What is going on with this article?

Rails Engineメモ

More than 3 years have passed since last update.

背景

Rails Engineを触ってみたのでメモ。

Engineとは何かなどは http://guides.rubyonrails.org/engines.html

サンプル

適当なサンプルということで、発生した例外をDBに保存するような仕組みを考える。

Engineの役目は、エラーの詳細を見るための画面や、例外保存処理をホストアプリに提供することである。

生成

rails plugin new error_catcher -T --dummy-path=spec/dummy --mountable

-Ttest関連の生成をスキップ。使い慣れているのがrspecなもので。。。

--dummy-path=spec/dummyは、engineの動作確認用のdummyのrailsアプリが生成されるパス。rspecを使うので、dummyアプリの置き場所もspec以下にする。

--mountableで、独立した名前空間を持ったskeltonが生成される。(正直ここはふわっとした理解)

rspecの準備

以下を追記。

error_catcher.gemspec
s.test_files = Dir["spec/**/*"]
s.add_development_dependency "rspec-rails"
lib/error_cathcer/engine.rb
config.generators do |g|
  g.test_framework :rspec
end

helperファイルを生成

bundle install
bin/rails g rspec:install

spec_helper.rbとかrails_helper.rbが生成される。

enviromentの読み込み先をdummyアプリに変える

spec/rails_helper.rb
require File.expand_path('../dummy/config/environment', __FILE__)

モデルを作成

bin/rails g scaffold error name:string description:string stacktrace:text fired_at:datetime
bundle exec rake db:migrate

ダミーアプリを起動

cd spec/dummy
bin/rails s

http://localhost:3000/error_catcher/errors

よくあるIndex画面が出るはず。

specを書いてみる

scaffoldで生成していれば、spec/models/error_cathcer/error_spec.rbが存在するはず。これを以下のように修正してみる。

spec/models/error_catcher/error_spec.rb
require 'rails_helper'

describe ErrorCatcher::Error do
  describe 'Validation' do
    it 'nameは必須' do
      error = described_class.new
      expect(error.valid?).to be_falsey
    end
  end
end

実装も直す。

app/models/error_catcher/error.rb
module ErrorCatcher
  class Error < ActiveRecord::Base
    validates :name, presence: true
  end
end
bundle exec rspec spec/models/error_cathcer/error_spec.rb

でテストが通るはず。

ホストアプリ側から呼び出すメソッドを実装する

ホストアプリ側からは、直接Modelを呼ぶのではなく例外保存用のインタフェースを呼ぶ。モデルを直接ホストアプリから呼ぶこともできるが、アプリとgemの依存関係が強くなってしまうので、別途外向けのインタフェースを用意する。

lib/error_catcher/catcher.rb
module ErrorCatcher
  module Catcher
    def catch e
      error = ::ErrorCatcher::Error.new
      error.name = e.class.name
      error.description = e.message
      error.stacktrace = e.backtrace.join("\n")
      error.fired_at = Time.now
      error.save!
    end
  end
end

アプリへ組み込み

error_catcherを利用する適当なアプリを作る。今回はerror_catcherと同じ階層に作る。

rails g new error_thrower
cd error_thrower
bin/rails g scafold item name:string description:string price:integer
Gemfile
gem 'error_catcher', path: '../error_catcher'
bundle install

error_catcherが提供するmigrationファイルを取得&migration。

bundle exec rake error_catcher:install:migrations
bundle exec rake db:migrate

コントローラで予期せぬ例外が起きたら全てキャッチして保存する。

error_thrower/app/controller/application_controller.rb
include ErrorCatcher::Catcher
rescue_from Exception, with: :error_handler

def error_handler e
  catch(e)
  render file: "#{Rails.root}/public/500.html", layout: false, status: 500
end

エラーが起きた時の動作確認のために、Validationをかける。

error_thrower/app/models/item.rb
validates :name, presence: true

error_thrower/app/controller/items_controller内の@item.saveを全て@item.save!に変えて、画面から空入力で保存するとValidationErrorが起きるようにする。

bin/rails s

http://localhost:3000/items/new から空で保存すると、エラー画面が表示され、http://localhost:3000/error_catcher/errors を見れば発生したエラーが保存されている。

これで、例外保存、閲覧の仕組みをRailsアプリに組み込むEngineができたことになる

作ったものはこちら https://github.com/hokuma/error_catcher

halhide
rubyとかjavascriptとか。
http://blog.hokuma.net
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした