rollbar 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +20 -0
- data/.travis.yml +17 -0
- data/CHANGELOG.md +90 -0
- data/Gemfile +8 -0
- data/LICENSE +22 -0
- data/README.md +165 -0
- data/Rakefile +14 -0
- data/THANKS +10 -0
- data/lib/generators/rollbar/rollbar_generator.rb +53 -0
- data/lib/generators/rollbar/templates/initializer.rb +28 -0
- data/lib/rollbar.rb +358 -0
- data/lib/rollbar/configuration.rb +64 -0
- data/lib/rollbar/delayed_job.rb +25 -0
- data/lib/rollbar/exception_reporter.rb +24 -0
- data/lib/rollbar/goalie.rb +33 -0
- data/lib/rollbar/middleware/rack/builder.rb +21 -0
- data/lib/rollbar/middleware/rack/test_session.rb +31 -0
- data/lib/rollbar/middleware/rails/show_exceptions.rb +26 -0
- data/lib/rollbar/rack.rb +9 -0
- data/lib/rollbar/rails.rb +22 -0
- data/lib/rollbar/rails/controller_methods.rb +28 -0
- data/lib/rollbar/railtie.rb +37 -0
- data/lib/rollbar/rake.rb +9 -0
- data/lib/rollbar/rake_tasks.rb +60 -0
- data/lib/rollbar/request_data_extractor.rb +115 -0
- data/lib/rollbar/sidekiq.rb +25 -0
- data/lib/rollbar/version.rb +3 -0
- data/rollbar.gemspec +24 -0
- data/spec/controllers/home_controller_spec.rb +180 -0
- data/spec/dummyapp/.gitignore +73 -0
- data/spec/dummyapp/Rakefile +7 -0
- data/spec/dummyapp/app/assets/javascripts/application.js +3 -0
- data/spec/dummyapp/app/assets/stylesheets/application.css.scss +37 -0
- data/spec/dummyapp/app/controllers/application_controller.rb +3 -0
- data/spec/dummyapp/app/controllers/home_controller.rb +25 -0
- data/spec/dummyapp/app/controllers/users_controller.rb +17 -0
- data/spec/dummyapp/app/helpers/.gitkeep +0 -0
- data/spec/dummyapp/app/mailers/.gitkeep +0 -0
- data/spec/dummyapp/app/models/.gitkeep +0 -0
- data/spec/dummyapp/app/models/user.rb +10 -0
- data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +27 -0
- data/spec/dummyapp/app/views/devise/registrations/new.html.erb +20 -0
- data/spec/dummyapp/app/views/devise/shared/_links.html.erb +25 -0
- data/spec/dummyapp/app/views/home/cause_exception.html.erb +1 -0
- data/spec/dummyapp/app/views/home/index.html.erb +4 -0
- data/spec/dummyapp/app/views/home/report_exception.html.erb +1 -0
- data/spec/dummyapp/app/views/layouts/_messages.html.erb +5 -0
- data/spec/dummyapp/app/views/layouts/_navigation.html.erb +21 -0
- data/spec/dummyapp/app/views/layouts/application.html.erb +25 -0
- data/spec/dummyapp/app/views/users/index.html.erb +8 -0
- data/spec/dummyapp/app/views/users/show.html.erb +3 -0
- data/spec/dummyapp/config.ru +4 -0
- data/spec/dummyapp/config/application.rb +60 -0
- data/spec/dummyapp/config/boot.rb +10 -0
- data/spec/dummyapp/config/database.yml +25 -0
- data/spec/dummyapp/config/environment.rb +5 -0
- data/spec/dummyapp/config/environments/development.rb +37 -0
- data/spec/dummyapp/config/environments/production.rb +67 -0
- data/spec/dummyapp/config/environments/test.rb +37 -0
- data/spec/dummyapp/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummyapp/config/initializers/devise.rb +233 -0
- data/spec/dummyapp/config/initializers/inflections.rb +15 -0
- data/spec/dummyapp/config/initializers/mime_types.rb +5 -0
- data/spec/dummyapp/config/initializers/rollbar.rb +20 -0
- data/spec/dummyapp/config/initializers/secret_token.rb +7 -0
- data/spec/dummyapp/config/initializers/session_store.rb +8 -0
- data/spec/dummyapp/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummyapp/config/locales/devise.en.yml +58 -0
- data/spec/dummyapp/config/locales/en.yml +5 -0
- data/spec/dummyapp/config/routes.rb +14 -0
- data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +46 -0
- data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +5 -0
- data/spec/dummyapp/db/schema.rb +35 -0
- data/spec/dummyapp/db/seeds.rb +12 -0
- data/spec/dummyapp/lib/assets/.gitkeep +0 -0
- data/spec/dummyapp/public/404.html +26 -0
- data/spec/dummyapp/public/422.html +26 -0
- data/spec/dummyapp/public/500.html +25 -0
- data/spec/dummyapp/public/favicon.ico +0 -0
- data/spec/dummyapp/script/rails +6 -0
- data/spec/requests/home_spec.rb +48 -0
- data/spec/rollbar_spec.rb +426 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/support/devise.rb +3 -0
- metadata +282 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rollbar
|
4
|
+
class Sidekiq
|
5
|
+
def call(worker, msg, queue)
|
6
|
+
begin
|
7
|
+
yield
|
8
|
+
rescue => e
|
9
|
+
msg.delete('backtrace')
|
10
|
+
msg.delete('error_backtrace')
|
11
|
+
msg.delete('error_message')
|
12
|
+
msg.delete('error_class')
|
13
|
+
|
14
|
+
Rollbar.report_exception(e, :params => msg)
|
15
|
+
raise
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Sidekiq.configure_server do |config|
|
22
|
+
config.server_middleware do |chain|
|
23
|
+
chain.add Rollbar::Sidekiq
|
24
|
+
end
|
25
|
+
end
|
data/rollbar.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/rollbar/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Brian Rue"]
|
6
|
+
gem.email = ["brian@rollbar.com"]
|
7
|
+
gem.description = %q{Rails plugin to catch and send exceptions to Rollbar}
|
8
|
+
gem.summary = %q{Reports exceptions to Rollbar}
|
9
|
+
gem.homepage = "https://github.com/rollbar/rollbar-gem"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.test_files = gem.files.grep(%r{^(spec)/})
|
13
|
+
gem.name = "rollbar"
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
gem.version = Rollbar::VERSION
|
16
|
+
|
17
|
+
gem.add_runtime_dependency 'multi_json', '~> 1.6.0'
|
18
|
+
|
19
|
+
gem.add_development_dependency 'rails', '~> 3.2.12'
|
20
|
+
gem.add_development_dependency 'devise', '>= 2.1.2'
|
21
|
+
gem.add_development_dependency 'rspec-rails', '~> 2.12.0'
|
22
|
+
gem.add_development_dependency 'database_cleaner', '>= 0.9.1'
|
23
|
+
gem.add_development_dependency 'girl_friday', '>= 0.11.1'
|
24
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HomeController do
|
4
|
+
let(:logger_mock) { double("Rails.logger").as_null_object }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
reset_configuration
|
8
|
+
Rollbar.configure do |config|
|
9
|
+
config.access_token = 'aaaabbbbccccddddeeeeffff00001111'
|
10
|
+
config.environment = ::Rails.env
|
11
|
+
config.root = ::Rails.root
|
12
|
+
config.framework = "Rails: #{::Rails::VERSION::STRING}"
|
13
|
+
config.logger = logger_mock
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "rollbar controller methods" do
|
18
|
+
# TODO run these for a a more-real request
|
19
|
+
it "should build valid request data" do
|
20
|
+
data = @controller.rollbar_request_data
|
21
|
+
data.should have_key(:params)
|
22
|
+
data.should have_key(:url)
|
23
|
+
data.should have_key(:user_ip)
|
24
|
+
data.should have_key(:headers)
|
25
|
+
data.should have_key(:GET)
|
26
|
+
data.should have_key(:session)
|
27
|
+
data.should have_key(:method)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should build empty person data when no one is logged-in" do
|
31
|
+
data = @controller.rollbar_person_data
|
32
|
+
data.should == {}
|
33
|
+
end
|
34
|
+
|
35
|
+
context "rollbar_filter_params" do
|
36
|
+
it "should filter files" do
|
37
|
+
name = "John Doe"
|
38
|
+
file_hash = {
|
39
|
+
:filename => "test.txt",
|
40
|
+
:type => "text/plain",
|
41
|
+
:head => {},
|
42
|
+
:tempfile => "dummy"
|
43
|
+
}
|
44
|
+
file = ActionDispatch::Http::UploadedFile.new(file_hash)
|
45
|
+
|
46
|
+
params = {
|
47
|
+
:name => name,
|
48
|
+
:a_file => file
|
49
|
+
}
|
50
|
+
|
51
|
+
filtered = controller.send(:rollbar_filtered_params, Rollbar.configuration.scrub_fields, params)
|
52
|
+
|
53
|
+
filtered[:name].should == name
|
54
|
+
filtered[:a_file].should be_a_kind_of(Hash)
|
55
|
+
filtered[:a_file][:content_type].should == file_hash[:type]
|
56
|
+
filtered[:a_file][:original_filename].should == file_hash[:filename]
|
57
|
+
filtered[:a_file][:size].should == file_hash[:tempfile].size
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should filter files in nested params" do
|
61
|
+
name = "John Doe"
|
62
|
+
file_hash = {
|
63
|
+
:filename => "test.txt",
|
64
|
+
:type => "text/plain",
|
65
|
+
:head => {},
|
66
|
+
:tempfile => "dummy"
|
67
|
+
}
|
68
|
+
file = ActionDispatch::Http::UploadedFile.new(file_hash)
|
69
|
+
|
70
|
+
params = {
|
71
|
+
:name => name,
|
72
|
+
:wrapper => {
|
73
|
+
:wrapper2 => {
|
74
|
+
:a_file => file,
|
75
|
+
:foo => "bar"
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
filtered = controller.send(:rollbar_filtered_params, Rollbar.configuration.scrub_fields, params)
|
81
|
+
|
82
|
+
filtered[:name].should == name
|
83
|
+
filtered[:wrapper][:wrapper2][:foo].should == "bar"
|
84
|
+
|
85
|
+
filtered_file = filtered[:wrapper][:wrapper2][:a_file]
|
86
|
+
filtered_file.should be_a_kind_of(Hash)
|
87
|
+
filtered_file[:content_type].should == file_hash[:type]
|
88
|
+
filtered_file[:original_filename].should == file_hash[:filename]
|
89
|
+
filtered_file[:size].should == file_hash[:tempfile].size
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should scrub the default scrub_fields" do
|
93
|
+
params = {
|
94
|
+
:passwd => "hidden",
|
95
|
+
:password => "hidden",
|
96
|
+
:secret => "hidden",
|
97
|
+
:notpass => "visible"
|
98
|
+
}
|
99
|
+
|
100
|
+
filtered = controller.send(:rollbar_filtered_params, Rollbar.configuration.scrub_fields, params)
|
101
|
+
|
102
|
+
filtered[:passwd].should == "******"
|
103
|
+
filtered[:password].should == "******"
|
104
|
+
filtered[:secret].should == "******"
|
105
|
+
filtered[:notpass].should == "visible"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should scrub custom scrub_fields" do
|
109
|
+
Rollbar.configure do |config|
|
110
|
+
config.scrub_fields = [:notpass, :secret]
|
111
|
+
end
|
112
|
+
|
113
|
+
params = {
|
114
|
+
:passwd => "visible",
|
115
|
+
:password => "visible",
|
116
|
+
:secret => "hidden",
|
117
|
+
:notpass => "hidden"
|
118
|
+
}
|
119
|
+
|
120
|
+
filtered = controller.send(:rollbar_filtered_params, Rollbar.configuration.scrub_fields, params)
|
121
|
+
|
122
|
+
filtered[:passwd].should == "visible"
|
123
|
+
filtered[:password].should == "visible"
|
124
|
+
filtered[:secret].should == "******"
|
125
|
+
filtered[:notpass].should == "******"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "rollbar_request_url" do
|
130
|
+
it "should build simple http urls" do
|
131
|
+
req = controller.request
|
132
|
+
req.host = 'rollbar.com'
|
133
|
+
|
134
|
+
controller.send(:rollbar_request_data)[:url].should == 'http://rollbar.com'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "rollbar_user_ip" do
|
139
|
+
it "should use X-Real-Ip when set" do
|
140
|
+
controller.request.env["HTTP_X_REAL_IP"] = '1.1.1.1'
|
141
|
+
controller.request.env["HTTP_X_FORWARDED_FOR"] = '1.2.3.4'
|
142
|
+
controller.send(:rollbar_request_data)[:user_ip].should == '1.1.1.1'
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should use X-Forwarded-For when set" do
|
146
|
+
controller.request.env["HTTP_X_FORWARDED_FOR"] = '1.2.3.4'
|
147
|
+
controller.send(:rollbar_request_data)[:user_ip].should == '1.2.3.4'
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should use the remote_addr when neither is set" do
|
151
|
+
controller.send(:rollbar_request_data)[:user_ip].should == '0.0.0.0'
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "GET 'index'" do
|
158
|
+
it "should be successful and report a message" do
|
159
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
160
|
+
get 'index'
|
161
|
+
response.should be_success
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "GET 'report_exception'" do
|
166
|
+
it "should raise a NameError and report an exception" do
|
167
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
168
|
+
|
169
|
+
get 'report_exception'
|
170
|
+
response.should be_success
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
after(:each) do
|
175
|
+
Rollbar.configure do |config|
|
176
|
+
config.logger = ::Rails.logger
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#----------------------------------------------------------------------------
|
2
|
+
# Ignore these files when commiting to a git repository.
|
3
|
+
#
|
4
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
5
|
+
#
|
6
|
+
# The original version of this file is found here:
|
7
|
+
# https://github.com/RailsApps/rails-composer/blob/master/files/gitignore.txt
|
8
|
+
#
|
9
|
+
# Corrections? Improvements? Create a GitHub issue:
|
10
|
+
# http://github.com/RailsApps/rails-composer/issues
|
11
|
+
#----------------------------------------------------------------------------
|
12
|
+
|
13
|
+
# bundler state
|
14
|
+
/.bundle
|
15
|
+
/vendor/bundle/
|
16
|
+
/vendor/ruby/
|
17
|
+
|
18
|
+
# minimal Rails specific artifacts
|
19
|
+
db/*.sqlite3
|
20
|
+
/log/*
|
21
|
+
/tmp/*
|
22
|
+
|
23
|
+
# various artifacts
|
24
|
+
**.war
|
25
|
+
*.rbc
|
26
|
+
*.sassc
|
27
|
+
.rspec
|
28
|
+
.redcar/
|
29
|
+
.sass-cache
|
30
|
+
/config/config.yml
|
31
|
+
/coverage.data
|
32
|
+
/coverage/
|
33
|
+
/db/*.javadb/
|
34
|
+
/db/*.sqlite3
|
35
|
+
/doc/api/
|
36
|
+
/doc/app/
|
37
|
+
/doc/features.html
|
38
|
+
/doc/specs.html
|
39
|
+
/public/cache
|
40
|
+
/public/stylesheets/compiled
|
41
|
+
/public/system/*
|
42
|
+
/spec/tmp/*
|
43
|
+
/cache
|
44
|
+
/capybara*
|
45
|
+
/capybara-*.html
|
46
|
+
/gems
|
47
|
+
/specifications
|
48
|
+
rerun.txt
|
49
|
+
pickle-email-*.html
|
50
|
+
|
51
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
52
|
+
# or operating system, you probably want to add a global ignore instead:
|
53
|
+
# git config --global core.excludesfile ~/.gitignore_global
|
54
|
+
#
|
55
|
+
# Here are some files you may want to ignore globally:
|
56
|
+
|
57
|
+
# scm revert files
|
58
|
+
**.orig
|
59
|
+
|
60
|
+
# Mac finder artifacts
|
61
|
+
.DS_Store
|
62
|
+
|
63
|
+
# Netbeans project directory
|
64
|
+
/nbproject/
|
65
|
+
|
66
|
+
# RubyMine project files
|
67
|
+
.idea
|
68
|
+
|
69
|
+
# Textmate project files
|
70
|
+
/*.tmproj
|
71
|
+
|
72
|
+
# vim artifacts
|
73
|
+
**.swp
|
@@ -0,0 +1,7 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
3
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
4
|
+
|
5
|
+
require File.expand_path('../config/application', __FILE__)
|
6
|
+
|
7
|
+
Dummy::Application.load_tasks
|
@@ -0,0 +1,37 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
14
|
+
.brand {
|
15
|
+
float: left;
|
16
|
+
padding-right: 8px;
|
17
|
+
}
|
18
|
+
ul.nav {
|
19
|
+
list-style: none;
|
20
|
+
margin: 0 0 2em;
|
21
|
+
padding: 0;
|
22
|
+
}
|
23
|
+
ul.nav li {
|
24
|
+
display: inline;
|
25
|
+
}
|
26
|
+
#flash_notice, #flash_alert {
|
27
|
+
padding: 5px 8px;
|
28
|
+
margin: 10px 0;
|
29
|
+
}
|
30
|
+
#flash_notice {
|
31
|
+
background-color: #CFC;
|
32
|
+
border: solid 1px #6C6;
|
33
|
+
}
|
34
|
+
#flash_alert {
|
35
|
+
background-color: #FCC;
|
36
|
+
border: solid 1px #C66;
|
37
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class HomeController < ApplicationController
|
2
|
+
def index
|
3
|
+
@users = User.all
|
4
|
+
|
5
|
+
Rollbar.report_message("Test message from controller with no data", "debug")
|
6
|
+
Rollbar.report_message("Test message from controller with extra data", "debug",
|
7
|
+
:foo => "bar", :num_users => @users.length)
|
8
|
+
end
|
9
|
+
|
10
|
+
def report_exception
|
11
|
+
begin
|
12
|
+
foo = bar
|
13
|
+
rescue => e
|
14
|
+
Rollbar.report_exception(e, rollbar_request_data, rollbar_person_data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def cause_exception
|
19
|
+
foo = bar
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_user
|
23
|
+
User.find_by_encrypted_password(cookies[:session_id])
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class UsersController < ApplicationController
|
2
|
+
before_filter :authenticate_user!
|
3
|
+
|
4
|
+
def index
|
5
|
+
@users = User.all
|
6
|
+
end
|
7
|
+
|
8
|
+
def show
|
9
|
+
@user = User.find(params[:id])
|
10
|
+
end
|
11
|
+
|
12
|
+
def start_session
|
13
|
+
@user = User.find(params[:id])
|
14
|
+
cookies[:session_id] = @user.encrypted_password
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
# Include default devise modules. Others available are:
|
3
|
+
# :token_authenticatable, :confirmable,
|
4
|
+
# :lockable, :timeoutable and :omniauthable
|
5
|
+
devise :database_authenticatable, :registerable,
|
6
|
+
:recoverable, :rememberable, :trackable, :validatable
|
7
|
+
|
8
|
+
# Setup accessible (or protected) attributes for your model
|
9
|
+
attr_accessible :name, :email, :password, :password_confirmation, :remember_me
|
10
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<h2>Edit <%= resource_name.to_s.humanize %></h2>
|
2
|
+
|
3
|
+
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
|
4
|
+
<%= devise_error_messages! %>
|
5
|
+
<p><%= f.label :name %><br />
|
6
|
+
<%= f.text_field :name %></p>
|
7
|
+
|
8
|
+
<div><%= f.label :email %><br />
|
9
|
+
<%= f.email_field :email %></div>
|
10
|
+
|
11
|
+
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
|
12
|
+
<%= f.password_field :password, :autocomplete => "off" %></div>
|
13
|
+
|
14
|
+
<div><%= f.label :password_confirmation %><br />
|
15
|
+
<%= f.password_field :password_confirmation %></div>
|
16
|
+
|
17
|
+
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
|
18
|
+
<%= f.password_field :current_password %></div>
|
19
|
+
|
20
|
+
<div><%= f.submit "Update" %></div>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<h3>Cancel my account</h3>
|
24
|
+
|
25
|
+
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
|
26
|
+
|
27
|
+
<%= link_to "Back", :back %>
|