Add support for Sinatra; decouple Rails. close #119
This commit is contained in:
parent
703cf2320e
commit
557b14d5fd
|
@ -8,6 +8,7 @@
|
|||
`create` so that an exception gets raised if it is appropriate to do so.
|
||||
- [#199](https://github.com/airblade/paper_trail/pull/199) - Rails 4 compatibility.
|
||||
- [#165](https://github.com/airblade/paper_trail/pull/165) - Namespaced the version class under the `PaperTrail` module.
|
||||
- [#119](https://github.com/airblade/paper_trail/issues/119) - Support for [Sinatra](http://www.sinatrarb.com/); decoupled gem from `Rails`.
|
||||
|
||||
|
||||
## 2.7.2
|
||||
|
|
16
README.md
16
README.md
|
@ -54,6 +54,22 @@ The Rails 2.3 code is on the [`rails2`](https://github.com/airblade/paper_trail/
|
|||
|
||||
4. Add `has_paper_trail` to the models you want to track.
|
||||
|
||||
### Sinatra
|
||||
|
||||
PaperTrail provides a helper extension that acts similar to the controller mixin it provides for `Rails` applications.
|
||||
|
||||
It will set `PaperTrail.whodunnit` to whatever is returned by a method named `user_for_paper_trail` which you can define inside your Sinatra Application. (by default it attempts to invoke a method named `current_user`)
|
||||
|
||||
If you're using the modular [Sinatra::Base](http://www.sinatrarb.com/intro.html#Modular%20vs.%20Classic%20Style) style of application, you will need to register the extension:
|
||||
|
||||
```ruby
|
||||
# bleh_app.rb
|
||||
require 'sinatra/base'
|
||||
|
||||
class BlehApp < Sinatra::Base
|
||||
register PaperTrail::Sinatra
|
||||
end
|
||||
```
|
||||
|
||||
## API Summary
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'railties', '~> 3.0'
|
||||
gem 'activerecord', '~> 3.0'
|
||||
|
||||
group :development, :test do
|
||||
|
@ -8,6 +7,13 @@ group :development, :test do
|
|||
gem 'shoulda', '~> 3.5'
|
||||
gem 'ffaker', '>= 1.15'
|
||||
|
||||
# Testing of Rails
|
||||
gem 'railties', '~> 3.0'
|
||||
|
||||
# Testing of Sinatra
|
||||
gem 'sinatra', '~> 1.0'
|
||||
gem 'rack-test', '>= 0.6'
|
||||
|
||||
# Use sqlite3 gem for regular Ruby
|
||||
gem 'sqlite3', '~> 1.2', :platform => :ruby
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
require 'paper_trail/config'
|
||||
require 'paper_trail/controller'
|
||||
require 'paper_trail/has_paper_trail'
|
||||
require 'paper_trail/cleaner'
|
||||
|
||||
require 'paper_trail/serializers/yaml'
|
||||
require 'paper_trail/serializers/json'
|
||||
# Require all frameworks and serializers
|
||||
Dir[File.join(File.dirname(__FILE__), 'paper_trail', 'frameworks', '*.rb')].each { |file| require file }
|
||||
Dir[File.join(File.dirname(__FILE__), 'paper_trail', 'serializers', '*.rb')].each { |file| require file }
|
||||
|
||||
# PaperTrail's module methods can be called in both models and controllers.
|
||||
module PaperTrail
|
||||
|
@ -88,9 +88,7 @@ module PaperTrail
|
|||
# Thread-safe hash to hold PaperTrail's data.
|
||||
# Initializing with needed default values.
|
||||
def self.paper_trail_store
|
||||
Thread.current[:paper_trail] ||= {
|
||||
:request_enabled_for_controller => true
|
||||
}
|
||||
Thread.current[:paper_trail] ||= { :request_enabled_for_controller => true }
|
||||
end
|
||||
|
||||
# Returns PaperTrail's configuration object.
|
||||
|
@ -110,6 +108,8 @@ ActiveSupport.on_load(:active_record) do
|
|||
include PaperTrail::Model
|
||||
end
|
||||
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
include PaperTrail::Controller
|
||||
if defined?(ActionController)
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
include PaperTrail::Rails::Controller
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
module PaperTrail
|
||||
module Controller
|
||||
|
||||
def self.included(base)
|
||||
base.before_filter :set_paper_trail_enabled_for_controller
|
||||
base.before_filter :set_paper_trail_whodunnit, :set_paper_trail_controller_info
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Returns the user who is responsible for any changes that occur.
|
||||
# By default this calls `current_user` and returns the result.
|
||||
#
|
||||
# Override this method in your controller to call a different
|
||||
# method, e.g. `current_person`, or anything you like.
|
||||
def user_for_paper_trail
|
||||
current_user if defined?(current_user)
|
||||
end
|
||||
|
||||
# Returns any information about the controller or request that you
|
||||
# want PaperTrail to store alongside any changes that occur. By
|
||||
# default this returns an empty hash.
|
||||
#
|
||||
# Override this method in your controller to return a hash of any
|
||||
# information you need. The hash's keys must correspond to columns
|
||||
# in your `versions` table, so don't forget to add any new columns
|
||||
# you need.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# {:ip => request.remote_ip, :user_agent => request.user_agent}
|
||||
#
|
||||
# The columns `ip` and `user_agent` must exist in your `versions` # table.
|
||||
#
|
||||
# Use the `:meta` option to `PaperTrail::Model::ClassMethods.has_paper_trail`
|
||||
# to store any extra model-level data you need.
|
||||
def info_for_paper_trail
|
||||
{}
|
||||
end
|
||||
|
||||
# Returns `true` (default) or `false` depending on whether PaperTrail should
|
||||
# be active for the current request.
|
||||
#
|
||||
# Override this method in your controller to specify when PaperTrail should
|
||||
# be off.
|
||||
def paper_trail_enabled_for_controller
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Tells PaperTrail whether versions should be saved in the current request.
|
||||
def set_paper_trail_enabled_for_controller
|
||||
::PaperTrail.enabled_for_controller = paper_trail_enabled_for_controller
|
||||
end
|
||||
|
||||
# Tells PaperTrail who is responsible for any changes that occur.
|
||||
def set_paper_trail_whodunnit
|
||||
::PaperTrail.whodunnit = user_for_paper_trail if paper_trail_enabled_for_controller
|
||||
end
|
||||
|
||||
# DEPRECATED: please use `set_paper_trail_whodunnit` instead.
|
||||
def set_whodunnit
|
||||
logger.warn '[PaperTrail]: the `set_whodunnit` controller method has been deprecated. Please rename to `set_paper_trail_whodunnit`.'
|
||||
set_paper_trail_whodunnit
|
||||
end
|
||||
|
||||
# Tells PaperTrail any information from the controller you want
|
||||
# to store alongside any changes that occur.
|
||||
def set_paper_trail_controller_info
|
||||
::PaperTrail.controller_info = info_for_paper_trail if paper_trail_enabled_for_controller
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,79 @@
|
|||
module PaperTrail
|
||||
module Rails
|
||||
module Controller
|
||||
|
||||
def self.included(base)
|
||||
if defined?(ActionController) && base == ActionController::Base
|
||||
base.before_filter :set_paper_trail_enabled_for_controller
|
||||
base.before_filter :set_paper_trail_whodunnit, :set_paper_trail_controller_info
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Returns the user who is responsible for any changes that occur.
|
||||
# By default this calls `current_user` and returns the result.
|
||||
#
|
||||
# Override this method in your controller to call a different
|
||||
# method, e.g. `current_person`, or anything you like.
|
||||
def user_for_paper_trail
|
||||
current_user if defined?(current_user)
|
||||
end
|
||||
|
||||
# Returns any information about the controller or request that you
|
||||
# want PaperTrail to store alongside any changes that occur. By
|
||||
# default this returns an empty hash.
|
||||
#
|
||||
# Override this method in your controller to return a hash of any
|
||||
# information you need. The hash's keys must correspond to columns
|
||||
# in your `versions` table, so don't forget to add any new columns
|
||||
# you need.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# {:ip => request.remote_ip, :user_agent => request.user_agent}
|
||||
#
|
||||
# The columns `ip` and `user_agent` must exist in your `versions` # table.
|
||||
#
|
||||
# Use the `:meta` option to `PaperTrail::Model::ClassMethods.has_paper_trail`
|
||||
# to store any extra model-level data you need.
|
||||
def info_for_paper_trail
|
||||
{}
|
||||
end
|
||||
|
||||
# Returns `true` (default) or `false` depending on whether PaperTrail should
|
||||
# be active for the current request.
|
||||
#
|
||||
# Override this method in your controller to specify when PaperTrail should
|
||||
# be off.
|
||||
def paper_trail_enabled_for_controller
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Tells PaperTrail whether versions should be saved in the current request.
|
||||
def set_paper_trail_enabled_for_controller
|
||||
::PaperTrail.enabled_for_controller = paper_trail_enabled_for_controller
|
||||
end
|
||||
|
||||
# Tells PaperTrail who is responsible for any changes that occur.
|
||||
def set_paper_trail_whodunnit
|
||||
::PaperTrail.whodunnit = user_for_paper_trail if paper_trail_enabled_for_controller
|
||||
end
|
||||
|
||||
# DEPRECATED: please use `set_paper_trail_whodunnit` instead.
|
||||
def set_whodunnit
|
||||
logger.warn '[PaperTrail]: the `set_whodunnit` controller method has been deprecated. Please rename to `set_paper_trail_whodunnit`.'
|
||||
set_paper_trail_whodunnit
|
||||
end
|
||||
|
||||
# Tells PaperTrail any information from the controller you want
|
||||
# to store alongside any changes that occur.
|
||||
def set_paper_trail_controller_info
|
||||
::PaperTrail.controller_info = info_for_paper_trail if paper_trail_enabled_for_controller
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
module PaperTrail
|
||||
module Sinatra
|
||||
|
||||
# Register this module inside your Sinatra application to gain access to controller-level methods used by PaperTrail
|
||||
def self.registered(app)
|
||||
app.helpers PaperTrail::Sinatra
|
||||
app.before { set_paper_trail_whodunnit }
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Returns the user who is responsible for any changes that occur.
|
||||
# By default this calls `current_user` and returns the result.
|
||||
#
|
||||
# Override this method in your controller to call a different
|
||||
# method, e.g. `current_person`, or anything you like.
|
||||
def user_for_paper_trail
|
||||
current_user if defined?(current_user)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Tells PaperTrail who is responsible for any changes that occur.
|
||||
def set_paper_trail_whodunnit
|
||||
::PaperTrail.whodunnit = user_for_paper_trail if ::PaperTrail.enabled?
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
if defined?(Sinatra)
|
||||
module Sinatra
|
||||
register PaperTrail::Sinatra
|
||||
end
|
||||
end
|
|
@ -15,12 +15,14 @@ Gem::Specification.new do |s|
|
|||
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
||||
s.require_paths = ['lib']
|
||||
|
||||
s.add_dependency 'railties', ['>= 3.0', '< 5.0']
|
||||
s.add_dependency 'activerecord', ['>= 3.0', '< 5.0']
|
||||
|
||||
s.add_development_dependency 'rake'
|
||||
s.add_development_dependency 'shoulda', '~> 3.5'
|
||||
s.add_development_dependency 'ffaker', '>= 1.15'
|
||||
s.add_development_dependency 'railties', ['>= 3.0', '< 5.0']
|
||||
s.add_development_dependency 'sinatra', '~> 1.0'
|
||||
s.add_development_dependency 'rack-test', '>= 0.6'
|
||||
|
||||
# JRuby support for the test ENV
|
||||
unless defined?(JRUBY_VERSION)
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
require 'test_helper'
|
||||
require 'sinatra/base'
|
||||
|
||||
# --- Tests for modular `Sinatra::Base` style ----
|
||||
class BaseApp < Sinatra::Base
|
||||
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: File.expand_path('../../dummy/db/test.sqlite3', __FILE__))
|
||||
register PaperTrail::Sinatra
|
||||
|
||||
get '/test' do
|
||||
w = Widget.create!(name: 'foo')
|
||||
'Hello'
|
||||
end
|
||||
|
||||
def current_user
|
||||
'foobar'
|
||||
end
|
||||
end
|
||||
|
||||
class PaperTrailModularSinatraTest < ActiveSupport::TestCase
|
||||
include Rack::Test::Methods
|
||||
|
||||
test 'baseline' do
|
||||
assert_nil Widget.first
|
||||
assert_nil Widget.create.versions.first.whodunnit
|
||||
end
|
||||
|
||||
context "`PaperTrail::Sinatra` in a `Sinatra::Base` application" do
|
||||
|
||||
def app
|
||||
@app ||= BaseApp
|
||||
end
|
||||
|
||||
should "sets the `user_for_paper_trail` from the `current_user` method" do
|
||||
get '/test'
|
||||
assert_equal 'Hello', last_response.body
|
||||
widget = Widget.first
|
||||
assert_not_nil widget
|
||||
assert_equal 1, widget.versions.size
|
||||
assert_equal 'foobar', widget.versions.first.whodunnit
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# --- Tests for non-modular `Sinatra::Application` style ----
|
||||
class Sinatra::Application
|
||||
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: File.expand_path('../../dummy/db/test.sqlite3', __FILE__))
|
||||
|
||||
get '/test' do
|
||||
w = Widget.create!(name: 'foo')
|
||||
'Hello'
|
||||
end
|
||||
|
||||
def current_user
|
||||
'foobar'
|
||||
end
|
||||
end
|
||||
|
||||
class PaperTrailSinatraTest < ActiveSupport::TestCase
|
||||
include Rack::Test::Methods
|
||||
|
||||
def app
|
||||
@app ||= Sinatra::Application
|
||||
end
|
||||
|
||||
test 'baseline' do
|
||||
assert_nil Widget.first
|
||||
assert_nil Widget.create.versions.first.whodunnit
|
||||
end
|
||||
|
||||
context "`PaperTrail::Sinatra` in a `Sinatra::Application` application" do
|
||||
|
||||
def app
|
||||
@app ||= BaseApp
|
||||
end
|
||||
|
||||
should "sets the `user_for_paper_trail` from the `current_user` method" do
|
||||
get '/test'
|
||||
assert_equal 'Hello', last_response.body
|
||||
widget = Widget.first
|
||||
assert_not_nil widget
|
||||
assert_equal 1, widget.versions.size
|
||||
assert_equal 'foobar', widget.versions.first.whodunnit
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue