acts_as_statused 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +78 -0
- data/lib/acts_as_statused.rb +88 -0
- data/test/test_acts_as_statused.rb +11 -0
- data/test/test_helper.rb +1 -0
- metadata +58 -0
data/README
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
README
|
2
|
+
========================================================================
|
3
|
+
Ok, so now I have a status, what’s the best way to check if an object is equal to that status? or How I learned to stop worrying and love the ‘acts_as_statused’ plugin
|
4
|
+
|
5
|
+
Great question, well, first make sure the object you want to check has a status! Remember, not all models in our system have statuses. If you’re confident that your model has a status then continue on.
|
6
|
+
|
7
|
+
In your model make sure you that you have the following near the top of your class definition:
|
8
|
+
|
9
|
+
acts_as_statused
|
10
|
+
|
11
|
+
That’s all the code you need to put in to have access to that objects status. You do NOT have to put the standard:
|
12
|
+
belongs_to :status
|
13
|
+
|
14
|
+
As a matter of fact if you do this I’ll personally beat you with your own shoe!
|
15
|
+
Well, you’re asking yourself, what does ‘acts_as_statused’ do? Great question! First thing is does it does the belongs_to assignment. The next thing it does is magic!
|
16
|
+
|
17
|
+
Several methods will be created that are similiar to the ones on Status, except these methods give you really great, and efficient, ways to check an objects status. Let’s look at some examples, shall we?
|
18
|
+
|
19
|
+
How to get an object’s status:
|
20
|
+
bob = User.find(1)
|
21
|
+
bob.status
|
22
|
+
|
23
|
+
That’s pretty straight forward, no surprises there. The .status method returns the status object for the that object.
|
24
|
+
How do I assert on object’s status is equal to another status?
|
25
|
+
bob = User.find(1)
|
26
|
+
bob.status_is_active?
|
27
|
+
bob.status_is_pending?
|
28
|
+
|
29
|
+
Each of these methods is generated in a very similar way to the methods described earlier on status. For each record in the status table a new .status_is_XXXXX? method is created. These methods are essentially doing the following:
|
30
|
+
def status_is_active?
|
31
|
+
self.status_id == Status.active.id
|
32
|
+
end
|
33
|
+
|
34
|
+
This, again, makes for very easy to read code. Example:
|
35
|
+
if bob.status_is_active?
|
36
|
+
puts "welcome back bob"
|
37
|
+
end
|
38
|
+
|
39
|
+
Don’t forget that as we add new statuses to the database, we get new methods without a single line of code! Yippie!!
|
40
|
+
How NOT to check an object’s status is equal to another status?
|
41
|
+
bob = User.find(1)
|
42
|
+
if bob.status == Status.active
|
43
|
+
puts "welcome back bob"
|
44
|
+
end
|
45
|
+
|
46
|
+
Not only is this code not pretty to look at, but it can also be a fairly expensive call. Again, I will administer beatings if I find people doing this sort of code!
|
47
|
+
How to tell if an objects status has changed?
|
48
|
+
bob = User.find(1)
|
49
|
+
assert bob.status_is_active?
|
50
|
+
puts bob.has_status_changed? (false)
|
51
|
+
bob.status = Status.pending
|
52
|
+
bob.update
|
53
|
+
puts bob.has_status_changed? (true)
|
54
|
+
puts bob.previous_status (this should return Status.active)
|
55
|
+
|
56
|
+
The ability to known if a.) the status has changed and b.) what it’s previous state is extremely useful, especially in observers. Here’s an example:
|
57
|
+
item = Item.find(1)
|
58
|
+
item.status = Status.pending
|
59
|
+
item.update
|
60
|
+
|
61
|
+
In the observer:
|
62
|
+
def after_update(item)
|
63
|
+
if item.has_status_changed?
|
64
|
+
if item.previous_status == Status.active
|
65
|
+
# do something
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
In the model there are call back hooks for before and after of each verb (create, update, save, destroy). Example:
|
71
|
+
def before_save_status_changed
|
72
|
+
#do something
|
73
|
+
end
|
74
|
+
def after_save_status_changed
|
75
|
+
#do something else
|
76
|
+
end
|
77
|
+
|
78
|
+
These call backs only get called if the status has changed.
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module ActiveRecord #:nodoc:
|
2
|
+
module Acts #:nodoc:
|
3
|
+
|
4
|
+
module Statused
|
5
|
+
def self.included(base) # :nodoc:
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def acts_as_statused(options = {}, &extension)
|
11
|
+
# don't allow multiple calls
|
12
|
+
return if self.included_modules.include?(ActiveRecord::Acts::Statused::ActMethods)
|
13
|
+
|
14
|
+
send :include, ActiveRecord::Acts::Statused::ActMethods
|
15
|
+
|
16
|
+
valid_status = []
|
17
|
+
valid_statuses = options[:only] if options.is_a?(Hash)
|
18
|
+
|
19
|
+
class_eval do
|
20
|
+
belongs_to :status
|
21
|
+
|
22
|
+
attr_accessor :previous_status
|
23
|
+
|
24
|
+
def after_find
|
25
|
+
self.previous_status = self.status if respond_to?:status_id
|
26
|
+
end
|
27
|
+
|
28
|
+
def status
|
29
|
+
Status.get(self.status_id)
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_status_changed?
|
33
|
+
return self.previous_status != self.status
|
34
|
+
end
|
35
|
+
|
36
|
+
begin
|
37
|
+
Status.find(:all).each do |status| #get all the statuses in the db.
|
38
|
+
# only define valid statuses
|
39
|
+
# EX: acts_as_statused :only => ['active', 'inactive', 'pending']
|
40
|
+
next unless valid_statuses.blank? || valid_statuses.include?(status.name)
|
41
|
+
|
42
|
+
define_method("status_is_#{status.name}?") do #define the method status_is_statusname?
|
43
|
+
return self.status_id == status.id
|
44
|
+
end
|
45
|
+
end
|
46
|
+
rescue
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
%w{save update create destroy}.each do |verb|
|
52
|
+
define_method("before_#{verb}_status_changed") do
|
53
|
+
#puts "before_#{verb}_status_changed"
|
54
|
+
end
|
55
|
+
|
56
|
+
define_method("after_#{verb}_status_changed") do
|
57
|
+
#puts "after_#{verb}_status_changed"
|
58
|
+
end
|
59
|
+
|
60
|
+
define_method("do_before_#{verb}_status_changed") do
|
61
|
+
eval %{before_#{verb}_status_changed if self.has_status_changed?}
|
62
|
+
end
|
63
|
+
|
64
|
+
define_method("do_after_#{verb}_status_changed") do
|
65
|
+
eval %{after_#{verb}_status_changed if self.has_status_changed?}
|
66
|
+
end
|
67
|
+
|
68
|
+
eval %{
|
69
|
+
before_#{verb} :do_before_#{verb}_status_changed
|
70
|
+
after_#{verb} :do_after_#{verb}_status_changed
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module ActMethods
|
77
|
+
def self.included(base) # :nodoc:
|
78
|
+
base.extend ClassMethods
|
79
|
+
end
|
80
|
+
|
81
|
+
module ClassMethods
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
ActiveRecord::Base.send :include, ActiveRecord::Acts::Statused
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "test/unit"
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: acts_as_statused
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2007-02-27 00:00:00 -05:00
|
8
|
+
summary: acts_as_statused
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
- lib
|
12
|
+
email:
|
13
|
+
homepage:
|
14
|
+
rubyforge_project:
|
15
|
+
description: "acts_as_statused was developed by: markbates"
|
16
|
+
autorequire:
|
17
|
+
- acts_as_statused
|
18
|
+
default_executable:
|
19
|
+
bindir: bin
|
20
|
+
has_rdoc: false
|
21
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 0.0.0
|
26
|
+
version:
|
27
|
+
platform: ruby
|
28
|
+
signing_key:
|
29
|
+
cert_chain:
|
30
|
+
post_install_message:
|
31
|
+
authors:
|
32
|
+
- markbates
|
33
|
+
files:
|
34
|
+
- lib/acts_as_statused.rb
|
35
|
+
- README
|
36
|
+
test_files:
|
37
|
+
- test/test_acts_as_statused.rb
|
38
|
+
- test/test_helper.rb
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
executables: []
|
44
|
+
|
45
|
+
extensions: []
|
46
|
+
|
47
|
+
requirements: []
|
48
|
+
|
49
|
+
dependencies:
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: acts_as_constant
|
52
|
+
version_requirement:
|
53
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 1.0.0
|
58
|
+
version:
|