ryanlowe-save_or_raise 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +15 -0
- data/MIT-LICENSE +23 -0
- data/README +81 -0
- data/Rakefile +10 -0
- data/init.rb +1 -0
- data/lib/save_or_raise.rb +10 -0
- data/save_or_raise.gemspec +16 -0
- metadata +69 -0
data/CHANGELOG
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2008 Ryan Lowe
|
2
|
+
|
3
|
+
http://ryanlowe.ca
|
4
|
+
http://disruptiveagility.com
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= save_or_raise
|
2
|
+
|
3
|
+
This plugin includes one new method for ActiveRecord::Base called
|
4
|
+
save_or_raise which does almost the same thing as
|
5
|
+
ActiveRecord::Base#save!
|
6
|
+
|
7
|
+
== save vs save!
|
8
|
+
|
9
|
+
The ActiveRecord::Base save method returns true if the model save
|
10
|
+
is successful and false if it is not successful. The save! method
|
11
|
+
returns true if the model save is successful and raises an exception
|
12
|
+
if it is not successful.
|
13
|
+
|
14
|
+
== utility
|
15
|
+
|
16
|
+
The save method is useful for control flow in cases where a failed
|
17
|
+
save can be handled gracefully:
|
18
|
+
|
19
|
+
if model.save
|
20
|
+
...
|
21
|
+
else
|
22
|
+
...
|
23
|
+
end
|
24
|
+
|
25
|
+
Sometimes the control flow - often within or called by a controller -
|
26
|
+
cannot handle an unsuccessful save gracefully. The programmer's
|
27
|
+
choices are:
|
28
|
+
|
29
|
+
1. Do not branch on the save call and ignore failures.
|
30
|
+
2. Throw an exception:
|
31
|
+
|
32
|
+
raise "Save failed!" unless model.save
|
33
|
+
|
34
|
+
3. Call save! which does the same as 2
|
35
|
+
|
36
|
+
The exception thrown by 2 and 3 will generate a 500 HTTP code for the user
|
37
|
+
in production but it will also notify an admin by email when used in combination
|
38
|
+
with a plugin like exception_notification. Result of choice 1 is possible data
|
39
|
+
corruption and invalid application state.
|
40
|
+
|
41
|
+
So doing 1 is just not a good idea!
|
42
|
+
|
43
|
+
== The problem with save!
|
44
|
+
|
45
|
+
...is that is poorly named. Ruby methods that end with an exclamation
|
46
|
+
point are a signal that they change the object they operate on.
|
47
|
+
|
48
|
+
An irb example:
|
49
|
+
|
50
|
+
>> a = " hello "
|
51
|
+
=> " hello "
|
52
|
+
>> b = a.strip!
|
53
|
+
=> "hello"
|
54
|
+
>> a
|
55
|
+
=> "hello"
|
56
|
+
|
57
|
+
The method strip! returns the result to b but also changes a.
|
58
|
+
|
59
|
+
The save! method does not change the ActiveRecord model it is called on any more
|
60
|
+
than the save method does. Also the name save! does not hint that it throws an
|
61
|
+
exception in the failure case.
|
62
|
+
|
63
|
+
Both of these things make the code that uses save! less readable.
|
64
|
+
|
65
|
+
== A Solution
|
66
|
+
|
67
|
+
This plugin implements a new ActiveRecord#Base method
|
68
|
+
|
69
|
+
save_or_raise(raiseable = ActiveRecord::RecordNotSaved)
|
70
|
+
|
71
|
+
which can be used the following ways:
|
72
|
+
|
73
|
+
model.save_or_raise # instead of model.save!
|
74
|
+
model.save_or_raise "Save failed!" # raises RuntimeError with this message on failure
|
75
|
+
model.save_or_raise CustomException # raises CustomException on failure
|
76
|
+
|
77
|
+
In all three cases the raised exception presents a 500 HTTP error to
|
78
|
+
the user in production if the save fails.
|
79
|
+
|
80
|
+
The save! method remains untouched and can still be used.
|
81
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
|
+
|
4
|
+
require(File.join(File.dirname(__FILE__), 'config', 'boot'))
|
5
|
+
|
6
|
+
require 'rake'
|
7
|
+
require 'rake/testtask'
|
8
|
+
require 'rake/rdoctask'
|
9
|
+
|
10
|
+
require 'tasks/rails'
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'save_or_raise'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "save_or_raise"
|
3
|
+
s.version = "0.1.1"
|
4
|
+
s.date = "2008-05-25"
|
5
|
+
s.summary = "A replacement for ActiveRecord::Base#save! for Ruby on Rails"
|
6
|
+
s.email = "rails@ryanlowe.ca"
|
7
|
+
s.homepage = "http://github.com/ryanlowe/save_or_raise"
|
8
|
+
s.description = "A replacement for ActiveRecord::Base#save! for Ruby on Rails"
|
9
|
+
s.has_rdoc = false
|
10
|
+
s.authors = ["Ryan Lowe"]
|
11
|
+
s.files = ["README", "CHANGELOG", "MIT-LICENSE","Rakefile", "save_or_raise.gemspec", "init.rb","lib/save_or_raise.rb"]
|
12
|
+
s.test_files = []
|
13
|
+
s.rdoc_options = ["--main", "README"]
|
14
|
+
s.extra_rdoc_files = ["README","CHANGELOG"]
|
15
|
+
s.add_dependency("rails", ["> 2.0.0"])
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ryanlowe-save_or_raise
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Lowe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-05-25 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.0
|
23
|
+
version:
|
24
|
+
description: A replacement for ActiveRecord::Base#save! for Ruby on Rails
|
25
|
+
email: rails@ryanlowe.ca
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- CHANGELOG
|
33
|
+
files:
|
34
|
+
- README
|
35
|
+
- CHANGELOG
|
36
|
+
- MIT-LICENSE
|
37
|
+
- Rakefile
|
38
|
+
- save_or_raise.gemspec
|
39
|
+
- init.rb
|
40
|
+
- lib/save_or_raise.rb
|
41
|
+
has_rdoc: false
|
42
|
+
homepage: http://github.com/ryanlowe/save_or_raise
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --main
|
46
|
+
- README
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.0.1
|
65
|
+
signing_key:
|
66
|
+
specification_version: 2
|
67
|
+
summary: A replacement for ActiveRecord::Base#save! for Ruby on Rails
|
68
|
+
test_files: []
|
69
|
+
|