active_record_ignored_attributes 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Rakefile +24 -0
- data/Readme.md +220 -0
- data/active_record_ignored_attributes.gemspec +29 -0
- data/lib/active_record_ignored_attributes/comparison.rb +0 -0
- data/lib/active_record_ignored_attributes/inspect.rb +20 -0
- data/lib/active_record_ignored_attributes/matchers/be_same_as.rb +22 -0
- data/lib/active_record_ignored_attributes/matchers.rb +1 -0
- data/lib/active_record_ignored_attributes/same_attributes_as.rb +7 -0
- data/lib/active_record_ignored_attributes/version.rb +3 -0
- data/lib/active_record_ignored_attributes.rb +26 -0
- data/spec/attributes_spec.rb +34 -0
- data/spec/inspect_spec.rb +21 -0
- data/spec/matchers_spec.rb +30 -0
- data/spec/same_as_spec.rb +25 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/database.mysql2.yml +3 -0
- data/spec/support/database.sqlite3.yml +2 -0
- data/spec/support/models/address.rb +11 -0
- data/spec/support/schema.rb +12 -0
- metadata +165 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
#require 'bundler'
|
4
|
+
#begin
|
5
|
+
# Bundler.setup(:default, :development)
|
6
|
+
#rescue Bundler::BundlerError => e
|
7
|
+
# $stderr.puts e.message
|
8
|
+
# $stderr.puts "Run `bundle install` to install missing gems"
|
9
|
+
# exit e.status_code
|
10
|
+
#end
|
11
|
+
|
12
|
+
#---------------------------------------------------------------------------------------------------
|
13
|
+
require 'rspec/core'
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
16
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
20
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
21
|
+
spec.rcov = true
|
22
|
+
end
|
23
|
+
|
24
|
+
task :default => :spec
|
data/Readme.md
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
ActiveRecord Ignored Attributes
|
2
|
+
===============================
|
3
|
+
|
4
|
+
Adds various behavior to Active Record models relating to the model's attributes:
|
5
|
+
|
6
|
+
* Allows you to compare Active Record objects based on their *attributes*, which often makes more sense than the built-in `==` operator (which does its comparisons based on the `id` attribute alone! — not always what you want!)
|
7
|
+
* You can configure which attributes, if any, should be excluded from the comparison
|
8
|
+
* Provides a customizable inspect method, which by default excludes the same attributes that are excluded when doing a `same_attributes_as?` comparison
|
9
|
+
|
10
|
+
Example
|
11
|
+
=======
|
12
|
+
|
13
|
+
Consider a User model that holds the notion of users that have a name.
|
14
|
+
|
15
|
+
ActiveRecord::Schema.define do
|
16
|
+
create_table :addresses, :force => true do |t|
|
17
|
+
t.string :name
|
18
|
+
t.text :address
|
19
|
+
t.string :city
|
20
|
+
t.string :state
|
21
|
+
t.string :postal_code
|
22
|
+
t.string :country
|
23
|
+
t.timestamps
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Address < ActiveRecord::Base
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
Default ActiveRecord `==` behavior:
|
32
|
+
|
33
|
+
a = Address.new(address: 'B St.')
|
34
|
+
b = Address.new(address: 'B St.')
|
35
|
+
a == b # => false
|
36
|
+
|
37
|
+
Using `same_as?`:
|
38
|
+
|
39
|
+
a = Address.new(address: 'B St.')
|
40
|
+
b = Address.new(address: 'B St.')
|
41
|
+
a.same_as?(b) # => true
|
42
|
+
|
43
|
+
a = Address.new(address: 'B St.')
|
44
|
+
b = Address.new(address: 'Nowhere Road')
|
45
|
+
a.same_as?(b) # => false
|
46
|
+
|
47
|
+
|
48
|
+
Installing
|
49
|
+
==========
|
50
|
+
|
51
|
+
Add to your `Gemfile`:
|
52
|
+
|
53
|
+
<pre>
|
54
|
+
gem "active_record_attributes_equality"
|
55
|
+
</pre>
|
56
|
+
|
57
|
+
If you want to *replace* the default ActiveRecord `==` operator with the `same_as?` behavior, you should be able to just override it, like this:
|
58
|
+
|
59
|
+
class ActiveRecord::Base
|
60
|
+
alias_method :==, :same_as?
|
61
|
+
end
|
62
|
+
|
63
|
+
Configuring which attributes are ignored
|
64
|
+
========================================
|
65
|
+
|
66
|
+
By default, `id`, `created_at`, and `updated_at` will be ignored.
|
67
|
+
|
68
|
+
If you want to *add* some ignored attributes to the default array (`[:id, :created_at, :updated_at]`), you can override `self.ignored_attributes` like so, referencing `super`:
|
69
|
+
|
70
|
+
class Address < ActiveRecord::Base
|
71
|
+
def self.ignored_attributes
|
72
|
+
super + [:name]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
If you want to override the defaults instead of appending to them, just don't reference `super`:
|
77
|
+
|
78
|
+
class Address < ActiveRecord::Base
|
79
|
+
def self.ignored_attributes
|
80
|
+
[:id, :name]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
`inspect_without_ignored_attributes`
|
85
|
+
------------------------------------
|
86
|
+
|
87
|
+
Now that you've declared which attributes you don't really care about, how about making it so you don't have to see them in your `inspect` output too? (The output from `inspect` is verbose enough as it is!!)
|
88
|
+
|
89
|
+
If you want to occasionally see the same output as the default `inspect` but without all those ignored attributes showing up, you can just call `object.inspect_without_ignored_attributes`:
|
90
|
+
|
91
|
+
address.inspect_without_ignored_attributes # => "#<Address address: nil, city: nil, country: nil, postal_code: nil, state: nil>"
|
92
|
+
|
93
|
+
# Compared to:
|
94
|
+
address.inspect # => "#<Address id: 1, name: nil, address: nil, city: nil, state: nil, postal_code: nil, country: nil, created_at: \"2011-08-19 18:07:39\", updated_at: \"2011-08-19 18:07:39\">"
|
95
|
+
|
96
|
+
But that is a lot to type every time. If you want inspect to *always* be more readable, you can override the ActiveRecord default like this:
|
97
|
+
|
98
|
+
class Address < ActiveRecord::Base
|
99
|
+
alias_method :inspect, :inspect_without_ignored_attributes
|
100
|
+
end
|
101
|
+
|
102
|
+
or even:
|
103
|
+
|
104
|
+
class ActiveRecord::Base
|
105
|
+
alias_method :inspect, :inspect_without_ignored_attributes
|
106
|
+
end
|
107
|
+
|
108
|
+
Customizable inspect method
|
109
|
+
---------------------------
|
110
|
+
|
111
|
+
If you want to customize inspect further and specify exactly which attributes to show (and, optionally which delimiters to bracket the string with), you can use `inspect_with`:
|
112
|
+
|
113
|
+
class Address < ActiveRecord::Base
|
114
|
+
def inspect
|
115
|
+
inspect_with([:city, :state, :country])
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
or:
|
120
|
+
|
121
|
+
class Address < ActiveRecord::Base
|
122
|
+
def inspect
|
123
|
+
inspect_with([:id, :name, :address, :city, :state, :postal_code, :country], ['{', '}'])
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
RSpec
|
129
|
+
=======
|
130
|
+
|
131
|
+
This gem comes with a `be_same_as` matcher for RSpec.
|
132
|
+
|
133
|
+
Add this to your spec_helper.rb:
|
134
|
+
|
135
|
+
require 'active_record_ignored_attributes/matchers'
|
136
|
+
|
137
|
+
Then in your specs you can write such nicely readable expectations as:
|
138
|
+
|
139
|
+
expected = Address.new({city: 'City', country: 'USA'})
|
140
|
+
Address.last.should be_same_as(expected)
|
141
|
+
|
142
|
+
a = Address.new(address: 'B St.')
|
143
|
+
b = Address.new(address: 'B St.')
|
144
|
+
a.should be_same_as?(b) # passes
|
145
|
+
|
146
|
+
a = Address.new(address: 'B St.')
|
147
|
+
b = Address.new(address: 'Nowhere Road')
|
148
|
+
a.should be_same_as?(b) # fails
|
149
|
+
|
150
|
+
and it will lovingly do a diff for you and only show you the attributes in each object that actually differed:
|
151
|
+
|
152
|
+
expected: #<Address address: "Nowhere Road">
|
153
|
+
got: #<Address address: "B St.">
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
Motivation
|
158
|
+
==========
|
159
|
+
|
160
|
+
The default ActiveRecord `==` behavior isn't always adequate, as you can probably tell from the example at the top, or by the fact that you are looking at this gem right now.
|
161
|
+
|
162
|
+
This is the implementation of `==` in [ActiveRecord](https://github.com/rails/rails/blob/3-0-10/activerecord/lib/active_record/base.rb):
|
163
|
+
|
164
|
+
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
|
165
|
+
# is of the same type and +self+ has an ID and it is equal to +comparison_object.id+.
|
166
|
+
#
|
167
|
+
# Note that new records are different from any other record by definition, unless the
|
168
|
+
# other record is the receiver itself. Besides, if you fetch existing records with
|
169
|
+
# +select+ and leave the ID out, you're on your own, this predicate will return false.
|
170
|
+
#
|
171
|
+
# Note also that destroying a record preserves its ID in the model instance, so deleted
|
172
|
+
# models are still comparable.
|
173
|
+
def ==(comparison_object)
|
174
|
+
comparison_object.equal?(self) ||
|
175
|
+
(comparison_object.instance_of?(self.class) &&
|
176
|
+
comparison_object.id == id && !comparison_object.new_record?)
|
177
|
+
end
|
178
|
+
|
179
|
+
That implementation is often fine when you are dealing with saved records, but isn't helpful *at all* when one or both of the objects being compared is not-yet-saved.
|
180
|
+
|
181
|
+
If you want to compare two model instances based on their attributes, you will probably want to *exclude* certain irrelevant attributes from your comparison, such as: `id`, `created_at`, and `updated_at`. (I would consider those to be more *metadata* about the record than part of the record's data itself.)
|
182
|
+
|
183
|
+
This might not matter when you are comparing two new (unsaved) records (since `id`, `created_at`, and `updated_at` will all be `nil` until saved), but I sometimes find it necessary to compare a *saved* object with an *unsaved* one (in which case == would give you false since nil != 5). Or I want to compare two *saved* objects to find out if they contain the same *data* (so the ActiveRecord `==` operator doesn't work, because it returns false if they have different `id`'s, even if they are otherwise identical).
|
184
|
+
|
185
|
+
See also: http://stackoverflow.com/questions/4738439/how-to-test-for-activerecord-object-equality
|
186
|
+
|
187
|
+
|
188
|
+
Questions and Ideas
|
189
|
+
===================
|
190
|
+
|
191
|
+
* Does such a gem already exist?
|
192
|
+
* All I've found so far is https://github.com/GnomesLab/active_record_attributes_equality
|
193
|
+
* What should the method be called? I don't think overriding the existing `==` operator is a good idea (as done in [active_record_attributes_equality](https://github.com/GnomesLab/active_record_attributes_equality)), so for now I'm calling it `same_attributes_as?` (aliased as `same_as?` since that's easier to type). Other runners up were `practically_same_as?` and `attributes_eql?`.
|
194
|
+
|
195
|
+
|
196
|
+
Possible improvements:
|
197
|
+
|
198
|
+
* Allow the default to be overridden with a class macro like `ignore_for_attributes_eql :last_signed_in_at, :updated_at`
|
199
|
+
|
200
|
+
Also, perhaps you want to set the default ignored attributes for a model but still wish to be able to override these defaults as needed...
|
201
|
+
|
202
|
+
address.same_as?(other_address, :ignore => [:addressable_type, :addressable_id])
|
203
|
+
address.same_as?(other_address, :only => [:city, :state, :country])
|
204
|
+
|
205
|
+
|
206
|
+
Contributing
|
207
|
+
============
|
208
|
+
|
209
|
+
Comments and contributions are welcome.
|
210
|
+
|
211
|
+
Please feel free to fork the project at http://github.com/TylerRick/active_record_ignored_attributes and to send pull requests.
|
212
|
+
|
213
|
+
Bugs can be reported at https://github.com/TylerRick/active_record_ignored_attributes/issues
|
214
|
+
|
215
|
+
License
|
216
|
+
=======
|
217
|
+
|
218
|
+
Copyright 2011, Tyler Rick
|
219
|
+
|
220
|
+
This is free software, distributed under the terms of the MIT License.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "active_record_ignored_attributes/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "active_record_ignored_attributes"
|
7
|
+
s.version = ActiveRecordIgnoredAttributes::Version
|
8
|
+
s.authors = ["Tyler Rick"]
|
9
|
+
s.email = ["tyler@tylerrick.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Allows you to compare Active Record objects based on their *attributes* (with same_as?), to exclude some attributes from being used in comparison, and adds improved inspect method}
|
12
|
+
s.description = s.summary
|
13
|
+
|
14
|
+
s.add_dependency 'activerecord'
|
15
|
+
s.add_dependency 'facets'
|
16
|
+
|
17
|
+
s.add_development_dependency 'rspec'
|
18
|
+
#s.add_development_dependency 'rcov'
|
19
|
+
s.add_development_dependency 'sqlite3'
|
20
|
+
s.add_development_dependency 'mysql2', '~>0.2.11'
|
21
|
+
s.add_development_dependency 'rr'
|
22
|
+
s.add_development_dependency 'activesupport'
|
23
|
+
s.add_development_dependency 'ruby-debug19'
|
24
|
+
|
25
|
+
s.files = `git ls-files`.split("\n")
|
26
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
27
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
28
|
+
s.require_paths = ["lib"]
|
29
|
+
end
|
File without changes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'facets/string/bracket'
|
2
|
+
|
3
|
+
module ActiveRecordIgnoredAttributes::Inspect
|
4
|
+
|
5
|
+
# TODO: brackets = self.class.default_brackets_for_inspect (configurable via class_inheritable_accessor)
|
6
|
+
|
7
|
+
def inspect_with(attr_names, brackets = ['#<', '>'])
|
8
|
+
attr_names ||= id
|
9
|
+
body = attr_names.map {|name|
|
10
|
+
"#{name}: #{send(name).inspect}"
|
11
|
+
}.join(', ')
|
12
|
+
|
13
|
+
"#{self.class} #{body}".
|
14
|
+
bracket(*brackets)
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect_without_ignored_attributes
|
18
|
+
inspect_with(attributes.keys - self.class.ignored_attributes.map(&:to_s))
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
RSpec::Matchers.define :be_same_as do |expected|
|
2
|
+
match do |actual|
|
3
|
+
actual.same_as?(expected)
|
4
|
+
end
|
5
|
+
|
6
|
+
failure_message_for_should do |actual|
|
7
|
+
#%(#{actual.inspect_without_ignored_attributes} was expected to have the same attributes as\n) +
|
8
|
+
#%(#{expected.inspect_without_ignored_attributes})
|
9
|
+
|
10
|
+
attr_names_that_differed = actual.attributes_without_ignored_attributes.select do |k,v|
|
11
|
+
expected[k] != v
|
12
|
+
end.map(&:first)
|
13
|
+
# TODO: pass extra option to inspect_with (such as the other object) so that it can use the same width for each attribute so that they line up nicely and are easy to visually compare
|
14
|
+
%(expected: #{expected.inspect_with(attr_names_that_differed)}\n) +
|
15
|
+
%( got: #{actual.inspect_with(attr_names_that_differed)})
|
16
|
+
end
|
17
|
+
|
18
|
+
failure_message_for_should_not do |actual|
|
19
|
+
%( expected: #{expected.inspect}\n) +
|
20
|
+
%(to not be same_as: #{actual.inspect})
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_record_ignored_attributes/matchers/be_same_as'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require "active_record_ignored_attributes/version"
|
3
|
+
require "active_record_ignored_attributes/inspect"
|
4
|
+
require "active_record_ignored_attributes/same_attributes_as"
|
5
|
+
|
6
|
+
module ActiveRecordIgnoredAttributes
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
# TODO: class_inheritable_accessor
|
11
|
+
def self.ignored_attributes
|
12
|
+
[:id, :created_at, :updated_at]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def attributes_without_ignored_attributes
|
17
|
+
attributes.except(*self.class.ignored_attributes.map(&:to_s))
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
ActiveRecord::Base.class_eval do
|
23
|
+
include ActiveRecordIgnoredAttributes
|
24
|
+
include ActiveRecordIgnoredAttributes::SameAttributesAs
|
25
|
+
include ActiveRecordIgnoredAttributes::Inspect
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Address do
|
4
|
+
describe 'attributes_without_ignored_attributes' do
|
5
|
+
let(:address) { Address.create! }
|
6
|
+
it 'should not include any of the ignored attributes' do
|
7
|
+
address.attributes_without_ignored_attributes.tap do |attributes|
|
8
|
+
attributes.should be_a(Hash)
|
9
|
+
attributes.should_not have_key('id')
|
10
|
+
attributes.should_not have_key('created_at')
|
11
|
+
attributes.should_not have_key('updated_at')
|
12
|
+
attributes.should_not have_key('name')
|
13
|
+
end
|
14
|
+
|
15
|
+
# Plain old 'attributes', on the other hand, does include them
|
16
|
+
address.attributes.tap do |attributes|
|
17
|
+
attributes.should be_a(Hash)
|
18
|
+
attributes.should have_key('id')
|
19
|
+
attributes.should have_key('created_at')
|
20
|
+
attributes.should have_key('updated_at')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should include all of the non-ignored attributes' do
|
25
|
+
address.attributes_without_ignored_attributes.tap do |attributes|
|
26
|
+
attributes.should be_a(Hash)
|
27
|
+
[:address, :city, :state, :postal_code, :country].each do |attr_name|
|
28
|
+
#puts "attributes.has_key?(#{attr_name})=#{attributes.has_key?(attr_name)}"
|
29
|
+
attributes.should have_key(attr_name.to_s)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Address do
|
4
|
+
describe 'inspect_without_ignored_attributes' do
|
5
|
+
let(:address) { Address.create }
|
6
|
+
it do
|
7
|
+
address.inspect_without_ignored_attributes.should_not match(/id:/)
|
8
|
+
address.inspect_without_ignored_attributes.should_not match(/name:/)
|
9
|
+
address.inspect_without_ignored_attributes.should_not match(/created_at:/)
|
10
|
+
address.original_inspect.should match(/#<Address id: \d+, .* created_at: ".*", updated_at: ".*">/)
|
11
|
+
address.inspect_without_ignored_attributes.should == "#<Address address: nil, city: nil, country: nil, postal_code: nil, state: nil>"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'inspect' do
|
16
|
+
let(:address) { Address.create }
|
17
|
+
it do
|
18
|
+
address.inspect.should match(/{Address id: \d+, name: nil, address: nil, city: nil, state: nil, postal_code: nil, country: nil}/)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require 'active_support/core_ext/string/strip'
|
3
|
+
|
4
|
+
describe "be_same_as" do
|
5
|
+
it "delegates to same_as?" do
|
6
|
+
object, other = Object.new, Object.new
|
7
|
+
mock(object).same_as?(other) { true }
|
8
|
+
object.should be_same_as(other)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "reports a nice failure message for should" do
|
12
|
+
object, other = Address.new(address: 'A Street'), Address.new(address: 'B Street')
|
13
|
+
expect do
|
14
|
+
object.should be_same_as(other)
|
15
|
+
end.should raise_error(<<-End.strip_heredoc.chomp)
|
16
|
+
expected: #<Address address: "B Street">
|
17
|
+
got: #<Address address: "A Street">
|
18
|
+
End
|
19
|
+
end
|
20
|
+
|
21
|
+
it "reports a nice failure message for should_not" do
|
22
|
+
object, other = Address.new(address: 'A Street'), Address.new(address: 'A Street')
|
23
|
+
expect do
|
24
|
+
object.should_not be_same_as(other)
|
25
|
+
end.should raise_error(<<-End.strip_heredoc.chomp)
|
26
|
+
expected: {Address id: nil, name: nil, address: "A Street", city: nil, state: nil, postal_code: nil, country: nil}
|
27
|
+
to not be same_as: {Address id: nil, name: nil, address: "A Street", city: nil, state: nil, postal_code: nil, country: nil}
|
28
|
+
End
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Address do
|
4
|
+
describe 'same_as?' do
|
5
|
+
let(:address) { Address.new }
|
6
|
+
|
7
|
+
it 'should return false even if any of the non-ignored attributes differ' do
|
8
|
+
a = Address.new(address: '123 A Street')
|
9
|
+
b = Address.new(address: '345 K Street')
|
10
|
+
|
11
|
+
a.should_not be_same_as(b)
|
12
|
+
a.attributes.should_not == b.attributes
|
13
|
+
a.attributes_without_ignored_attributes.should_not == b.attributes_without_ignored_attributes
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should still return true even if some of the ignored attributes differ' do
|
17
|
+
a = Address.new(name: 'A', address: 'The Same Address')
|
18
|
+
b = Address.new(name: 'B', address: 'The Same Address')
|
19
|
+
|
20
|
+
a.should be_same_as(b)
|
21
|
+
a.attributes.should_not == b.attributes
|
22
|
+
a.attributes_without_ignored_attributes.should == b.attributes_without_ignored_attributes
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
__DIR__ = Pathname.new(__FILE__).dirname
|
2
|
+
$LOAD_PATH.unshift __DIR__
|
3
|
+
$LOAD_PATH.unshift __DIR__ + '../lib'
|
4
|
+
|
5
|
+
#---------------------------------------------------------------------------------------------------
|
6
|
+
# ActiveRecord
|
7
|
+
|
8
|
+
require 'active_record'
|
9
|
+
driver = ENV["DB"] || 'sqlite3'
|
10
|
+
#require driver
|
11
|
+
database_config = YAML::load(File.open(__DIR__ + "support/database.#{driver}.yml"))
|
12
|
+
ActiveRecord::Base.establish_connection(database_config)
|
13
|
+
|
14
|
+
#---------------------------------------------------------------------------------------------------
|
15
|
+
# RSpec
|
16
|
+
|
17
|
+
require 'rspec'
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.mock_with :rr
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'active_record_ignored_attributes'
|
24
|
+
require 'active_record_ignored_attributes/matchers'
|
25
|
+
|
26
|
+
# Requires supporting ruby files in spec/support/
|
27
|
+
Dir[__DIR__ + 'support/**/*.rb'].each do |f|
|
28
|
+
require f
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_record_ignored_attributes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tyler Rick
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-08-19 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: activerecord
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: facets
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: rspec
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: sqlite3
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: mysql2
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.2.11
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: rr
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: activesupport
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id007
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: ruby-debug19
|
95
|
+
prerelease: false
|
96
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: "0"
|
102
|
+
type: :development
|
103
|
+
version_requirements: *id008
|
104
|
+
description: Allows you to compare Active Record objects based on their *attributes* (with same_as?), to exclude some attributes from being used in comparison, and adds improved inspect method
|
105
|
+
email:
|
106
|
+
- tyler@tylerrick.com
|
107
|
+
executables: []
|
108
|
+
|
109
|
+
extensions: []
|
110
|
+
|
111
|
+
extra_rdoc_files: []
|
112
|
+
|
113
|
+
files:
|
114
|
+
- .gitignore
|
115
|
+
- .rspec
|
116
|
+
- Gemfile
|
117
|
+
- Rakefile
|
118
|
+
- Readme.md
|
119
|
+
- active_record_ignored_attributes.gemspec
|
120
|
+
- lib/active_record_ignored_attributes.rb
|
121
|
+
- lib/active_record_ignored_attributes/comparison.rb
|
122
|
+
- lib/active_record_ignored_attributes/inspect.rb
|
123
|
+
- lib/active_record_ignored_attributes/matchers.rb
|
124
|
+
- lib/active_record_ignored_attributes/matchers/be_same_as.rb
|
125
|
+
- lib/active_record_ignored_attributes/same_attributes_as.rb
|
126
|
+
- lib/active_record_ignored_attributes/version.rb
|
127
|
+
- spec/attributes_spec.rb
|
128
|
+
- spec/inspect_spec.rb
|
129
|
+
- spec/matchers_spec.rb
|
130
|
+
- spec/same_as_spec.rb
|
131
|
+
- spec/spec_helper.rb
|
132
|
+
- spec/support/database.mysql2.yml
|
133
|
+
- spec/support/database.sqlite3.yml
|
134
|
+
- spec/support/models/address.rb
|
135
|
+
- spec/support/schema.rb
|
136
|
+
has_rdoc: true
|
137
|
+
homepage: ""
|
138
|
+
licenses: []
|
139
|
+
|
140
|
+
post_install_message:
|
141
|
+
rdoc_options: []
|
142
|
+
|
143
|
+
require_paths:
|
144
|
+
- lib
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: "0"
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: "0"
|
157
|
+
requirements: []
|
158
|
+
|
159
|
+
rubyforge_project:
|
160
|
+
rubygems_version: 1.5.2
|
161
|
+
signing_key:
|
162
|
+
specification_version: 3
|
163
|
+
summary: Allows you to compare Active Record objects based on their *attributes* (with same_as?), to exclude some attributes from being used in comparison, and adds improved inspect method
|
164
|
+
test_files: []
|
165
|
+
|