filthy 1.0.0
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/Manifest +8 -0
- data/README.md +40 -0
- data/Rakefile +14 -0
- data/filthy.gemspec +45 -0
- data/lib/filthy.rb +53 -0
- data/test/database.yml +3 -0
- data/test/filthy_test.rb +88 -0
- data/test/helper.rb +31 -0
- metadata +148 -0
data/Manifest
ADDED
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Filthy
|
2
|
+
|
3
|
+
Rails gem to check if an attribute was changed on the last save. Useful in after_save callbacks.
|
4
|
+
|
5
|
+
# Install
|
6
|
+
```bash
|
7
|
+
gem install filthy
|
8
|
+
```
|
9
|
+
### Usage
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
class Movie < ActiveRecord::Base
|
13
|
+
|
14
|
+
filthy_attributes :title, :director
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
@movie = Movie.find(1)
|
19
|
+
@movie.title = "28 days later"
|
20
|
+
@movie.title_filthy?
|
21
|
+
=> false
|
22
|
+
@movie.save
|
23
|
+
=> true
|
24
|
+
@movie.title_filthy?
|
25
|
+
=> true
|
26
|
+
@movie.save
|
27
|
+
=> true
|
28
|
+
@movie.title_filthy?
|
29
|
+
=> false
|
30
|
+
```
|
31
|
+
|
32
|
+
# Credits
|
33
|
+
|
34
|
+
Filthy is maintained by [Mike Taylor](http://github.com/sealabcore) and is funded by [BookRenter.com](http://www.bookrenter.com "BookRenter.com"). Many of the ideas that have inspired Filthy come from practical usage by the Bookrenter software development team and conversations with Bookrenter developers [Andrew Wheeler](http://github.com/jawheeler), [Michael Pearce](http://github.com/michaelgpearce), and [Philippe Huibonhoa](http://github.com/phuibonhoa).
|
35
|
+
|
36
|
+

|
37
|
+
|
38
|
+
# Copyright
|
39
|
+
|
40
|
+
Copyright (c) 2012 Mike Taylor, Bookrenter.com.
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('filthy', '1.0.0') do |p|
|
6
|
+
p.description = "Check if an attribute was changed after the last save."
|
7
|
+
p.url = "http://github.com/sealabcore/filthy"
|
8
|
+
p.author = "Mike Taylor"
|
9
|
+
p.email = "michael.taylor@bookrenter.com"
|
10
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
+
p.development_dependencies = ["sqlite3", "active_record", "active_support", 'test/unit', 'shoulda-context']
|
12
|
+
end
|
13
|
+
|
14
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/filthy.gemspec
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "filthy"
|
5
|
+
s.version = "1.0.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Mike Taylor"]
|
9
|
+
s.date = "2012-01-20"
|
10
|
+
s.description = "Check if an attribute was changed after the last save."
|
11
|
+
s.email = "michael.taylor@bookrenter.com"
|
12
|
+
s.extra_rdoc_files = ["README.md", "lib/filthy.rb"]
|
13
|
+
s.files = ["README.md", "Rakefile", "filthy.gemspec", "lib/filthy.rb", "test/database.yml", "test/filthy_test.rb", "test/helper.rb", "Manifest"]
|
14
|
+
s.homepage = "http://github.com/sealabcore/filthy"
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Filthy", "--main", "README.md"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = "filthy"
|
18
|
+
s.rubygems_version = "1.8.10"
|
19
|
+
s.summary = "Check if an attribute was changed after the last save."
|
20
|
+
s.test_files = ["test/filthy_test.rb"]
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
27
|
+
s.add_development_dependency(%q<active_record>, [">= 0"])
|
28
|
+
s.add_development_dependency(%q<active_support>, [">= 0"])
|
29
|
+
s.add_development_dependency(%q<test/unit>, [">= 0"])
|
30
|
+
s.add_development_dependency(%q<shoulda-context>, [">= 0"])
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
33
|
+
s.add_dependency(%q<active_record>, [">= 0"])
|
34
|
+
s.add_dependency(%q<active_support>, [">= 0"])
|
35
|
+
s.add_dependency(%q<test/unit>, [">= 0"])
|
36
|
+
s.add_dependency(%q<shoulda-context>, [">= 0"])
|
37
|
+
end
|
38
|
+
else
|
39
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
40
|
+
s.add_dependency(%q<active_record>, [">= 0"])
|
41
|
+
s.add_dependency(%q<active_support>, [">= 0"])
|
42
|
+
s.add_dependency(%q<test/unit>, [">= 0"])
|
43
|
+
s.add_dependency(%q<shoulda-context>, [">= 0"])
|
44
|
+
end
|
45
|
+
end
|
data/lib/filthy.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_support'
|
3
|
+
|
4
|
+
module Filthy
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
def filthy_attributes(*args)
|
9
|
+
class_variable_set(:@@filthy_attributes, args)
|
10
|
+
|
11
|
+
class_variable_set(:@@filthy_attribute_methods, class_variable_get(:@@filthy_attributes).collect { |attribute| :"#{attribute}_filthy" })
|
12
|
+
|
13
|
+
class_variable_get(:@@filthy_attribute_methods).each do |method|
|
14
|
+
attr_accessor method
|
15
|
+
|
16
|
+
send(:define_method, :"#{method}?") do
|
17
|
+
!!send(method)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module InstanceMethods
|
24
|
+
|
25
|
+
def has_filthy_attributes?
|
26
|
+
self.class.class_variables.include?("@@filthy_attributes")
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_filthy_before_save
|
30
|
+
clean_filthy_attributes
|
31
|
+
filthy_attributes = changes.keys.select { |attribute| self.class.send(:class_variable_get, :@@filthy_attributes).include? attribute.to_sym }
|
32
|
+
filthy_attributes.each do |filthy_attribute|
|
33
|
+
send("#{filthy_attribute}_filthy=", true)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def clean_filthy_attributes
|
38
|
+
self.class.send(:class_variable_get, :@@filthy_attribute_methods).each { |fa| send("#{fa}=", nil) }
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.included(base)
|
44
|
+
base.extend ClassMethods
|
45
|
+
base.send(:include, InstanceMethods)
|
46
|
+
base.before_save :set_filthy_before_save, :if => Proc.new { |object| object.has_filthy_attributes? }
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
class ActiveRecord::Base
|
52
|
+
include Filthy
|
53
|
+
end
|
data/test/database.yml
ADDED
data/test/filthy_test.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[helper])
|
2
|
+
|
3
|
+
class MovieTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "filthy_attributes" do
|
6
|
+
setup do
|
7
|
+
@movie = Movie.new
|
8
|
+
end
|
9
|
+
|
10
|
+
context "with passed attributes" do
|
11
|
+
context "on a new record" do
|
12
|
+
should "create accessors" do
|
13
|
+
assert_nil @movie.director_filthy
|
14
|
+
assert_nil @movie.title_filthy
|
15
|
+
end
|
16
|
+
|
17
|
+
should "create boolean methods" do
|
18
|
+
assert !@movie.director_filthy?
|
19
|
+
assert !@movie.title_filthy?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "after_save" do
|
24
|
+
setup do
|
25
|
+
@movie.title = "The Dream Warrior"
|
26
|
+
@movie.save
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when only title changed" do
|
30
|
+
should "be true for filthy attributese" do
|
31
|
+
assert @movie.title_filthy?
|
32
|
+
assert !@movie.director_filthy?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "after another save" do
|
37
|
+
setup do
|
38
|
+
@movie.director = "Rob Zombie"
|
39
|
+
@movie.save
|
40
|
+
end
|
41
|
+
|
42
|
+
should "be true for filthy attributes" do
|
43
|
+
assert !@movie.title_filthy?
|
44
|
+
assert @movie.director_filthy?
|
45
|
+
end
|
46
|
+
|
47
|
+
context "after another save when nothing changed" do
|
48
|
+
setup do
|
49
|
+
@movie.save
|
50
|
+
end
|
51
|
+
|
52
|
+
should "not have filthy attributes" do
|
53
|
+
assert !@movie.title_filthy?
|
54
|
+
assert !@movie.director_filthy?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "a model without filthy attributes" do
|
63
|
+
setup do
|
64
|
+
@actor = Actor.new
|
65
|
+
end
|
66
|
+
|
67
|
+
should "save" do
|
68
|
+
assert @actor.save
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "a model with filthy attributes" do
|
73
|
+
context "with a subclass with no filthy_attributes defined" do
|
74
|
+
setup do
|
75
|
+
@short = Short.new
|
76
|
+
@short.title = "Intruder"
|
77
|
+
@short.save
|
78
|
+
end
|
79
|
+
|
80
|
+
should "have filthy attributes" do
|
81
|
+
assert !@short.director_filthy?
|
82
|
+
assert @short.title_filthy?
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'sqlite3'
|
4
|
+
require 'filthy'
|
5
|
+
require 'shoulda-context'
|
6
|
+
|
7
|
+
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
8
|
+
ActiveRecord::Base.establish_connection(config['test'])
|
9
|
+
|
10
|
+
ActiveRecord::Base.connection.create_table :movies, :force => true do |table|
|
11
|
+
table.column :title, :string
|
12
|
+
table.column :director, :string
|
13
|
+
end
|
14
|
+
|
15
|
+
ActiveRecord::Base.connection.create_table :actors, :force => true do |table|
|
16
|
+
table.column :id, :integer
|
17
|
+
table.column :name, :string
|
18
|
+
end
|
19
|
+
|
20
|
+
class Movie < ActiveRecord::Base
|
21
|
+
|
22
|
+
filthy_attributes :title, :director
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class Short < Movie
|
27
|
+
end
|
28
|
+
|
29
|
+
class Actor < ActiveRecord::Base
|
30
|
+
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: filthy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Mike Taylor
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-01-20 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: sqlite3
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: active_record
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: active_support
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
type: :development
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: test/unit
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
type: :development
|
75
|
+
version_requirements: *id004
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: shoulda-context
|
78
|
+
prerelease: false
|
79
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
type: :development
|
89
|
+
version_requirements: *id005
|
90
|
+
description: Check if an attribute was changed after the last save.
|
91
|
+
email: michael.taylor@bookrenter.com
|
92
|
+
executables: []
|
93
|
+
|
94
|
+
extensions: []
|
95
|
+
|
96
|
+
extra_rdoc_files:
|
97
|
+
- README.md
|
98
|
+
- lib/filthy.rb
|
99
|
+
files:
|
100
|
+
- README.md
|
101
|
+
- Rakefile
|
102
|
+
- filthy.gemspec
|
103
|
+
- lib/filthy.rb
|
104
|
+
- test/database.yml
|
105
|
+
- test/filthy_test.rb
|
106
|
+
- test/helper.rb
|
107
|
+
- Manifest
|
108
|
+
homepage: http://github.com/sealabcore/filthy
|
109
|
+
licenses: []
|
110
|
+
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options:
|
113
|
+
- --line-numbers
|
114
|
+
- --inline-source
|
115
|
+
- --title
|
116
|
+
- Filthy
|
117
|
+
- --main
|
118
|
+
- README.md
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
hash: 3
|
127
|
+
segments:
|
128
|
+
- 0
|
129
|
+
version: "0"
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
hash: 11
|
136
|
+
segments:
|
137
|
+
- 1
|
138
|
+
- 2
|
139
|
+
version: "1.2"
|
140
|
+
requirements: []
|
141
|
+
|
142
|
+
rubyforge_project: filthy
|
143
|
+
rubygems_version: 1.8.10
|
144
|
+
signing_key:
|
145
|
+
specification_version: 3
|
146
|
+
summary: Check if an attribute was changed after the last save.
|
147
|
+
test_files:
|
148
|
+
- test/filthy_test.rb
|