safe_attributes 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.rdoc +17 -2
- data/VERSION +1 -1
- data/lib/safe_attributes.rb +46 -39
- data/safe_attributes.gemspec +2 -2
- data/spec/safe_attributes/safe_attributes_spec.rb +87 -78
- metadata +4 -4
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -26,6 +26,8 @@ that this module does not prevent the creation of:
|
|
26
26
|
|
27
27
|
These largely should not run afoul of Ruby or ActiveRecord in most cases.
|
28
28
|
|
29
|
+
== Accessing Attributes
|
30
|
+
|
29
31
|
To access an attribute in ActiveRecord without its normal getter or setter
|
30
32
|
you can use a couple of different approaches.
|
31
33
|
|
@@ -35,6 +37,13 @@ you can use a couple of different approaches.
|
|
35
37
|
|
36
38
|
You can read more about reserved words[http://oldwiki.rubyonrails.org/rails/pages/ReservedWords] and magic field names[http://oldwiki.rubyonrails.org/rails/pages/MagicFieldNames] on Rails' wiki pages.
|
37
39
|
|
40
|
+
== Validations
|
41
|
+
|
42
|
+
By including safe_attributes, an instance method read_attribute_for_validation
|
43
|
+
is defined in a way that will work for all attributes instead of the
|
44
|
+
default implementation that relies upon the default accessors. In other
|
45
|
+
words, `validates_presence_of :class' will work as of version 1.0.3.
|
46
|
+
|
38
47
|
== Installing
|
39
48
|
|
40
49
|
gem install safe_attributes
|
@@ -60,10 +69,12 @@ Add safe_attributes to your Gemfile.
|
|
60
69
|
|
61
70
|
SafeAttributes is included into ActiveRecord::Base automatically. While
|
62
71
|
nothing else should be necessary, you can still add to the list of bad
|
63
|
-
attributes if you find it necessary.
|
72
|
+
attributes if you find it necessary. This list is a list of method names
|
73
|
+
not to generate.
|
64
74
|
|
65
75
|
class MyModel < ActiveRecord::Base
|
66
76
|
bad_attribute_names :my_attr
|
77
|
+
validates_presence_of :my_attr
|
67
78
|
end
|
68
79
|
|
69
80
|
=== Outside of Rails
|
@@ -84,4 +95,8 @@ attributes if you find it necessary.
|
|
84
95
|
|
85
96
|
== Copyright
|
86
97
|
|
87
|
-
Copyright (c) 2010 C. Brian Jones. See LICENSE for details.
|
98
|
+
Copyright (c) 2010,2011 C. Brian Jones. See LICENSE for details.
|
99
|
+
|
100
|
+
== Thanks
|
101
|
+
|
102
|
+
* Jaime Bellmyer - http://kconrails.com
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.3
|
data/lib/safe_attributes.rb
CHANGED
@@ -1,47 +1,54 @@
|
|
1
1
|
module SafeAttributes
|
2
|
-
|
2
|
+
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
4
|
+
module ClassMethods
|
5
|
+
#
|
6
|
+
# Within your model call this method once with a list of
|
7
|
+
# methods matching either attribute() or attribute=() for
|
8
|
+
# attributes (column names) you do not want to create the
|
9
|
+
# the normal method for. You should not need to do this
|
10
|
+
# but the option is there in case the default list is
|
11
|
+
# inadequate.
|
12
|
+
#
|
13
|
+
def bad_attribute_names(*attrs)
|
14
|
+
@bad_attribute_names ||= lambda {
|
15
|
+
methods = Array.new(attrs.collect { |x| x.to_s })
|
16
|
+
methods += ActiveRecord::Base.public_instance_methods
|
17
|
+
methods += ActiveRecord::Base.protected_instance_methods
|
18
|
+
methods += ActiveRecord::Base.private_instance_methods
|
19
|
+
methods -= ['id']
|
20
|
+
return methods
|
21
|
+
}.call
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
#
|
25
|
+
# Override the default implementation to not create the
|
26
|
+
# attribute() method if that method name is in the list of
|
27
|
+
# bad names
|
28
|
+
#
|
29
|
+
def define_method_attribute(attr_name)
|
30
|
+
return if (bad_attribute_names.include?(attr_name))
|
31
|
+
super(attr_name)
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
34
|
+
#
|
35
|
+
# Override the default implementation to not create the
|
36
|
+
# attribute= method if that method name is in the list of
|
37
|
+
# bad names
|
38
|
+
#
|
39
|
+
def define_method_attribute=(attr_name)
|
40
|
+
method = attr_name + '='
|
41
|
+
return if (bad_attribute_names.include?(method))
|
42
|
+
super(attr_name)
|
44
43
|
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module InstanceMethods
|
47
|
+
def read_attribute_for_validation(attr)
|
48
|
+
self[attr.to_sym]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
45
52
|
end
|
46
53
|
|
47
54
|
require 'safe_attributes/railtie.rb' if defined?(Rails)
|
data/safe_attributes.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{safe_attributes}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Jones"]
|
12
|
-
s.date = %q{2011-01
|
12
|
+
s.date = %q{2011-02-01}
|
13
13
|
s.description = %q{Better support for legacy database schemas for ActiveRecord, such as columns named class, or any other name that conflicts with an instance method of ActiveRecord.}
|
14
14
|
s.email = %q{cbj@gnu.org}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -3,90 +3,99 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
3
3
|
# create the table for the test in the database
|
4
4
|
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'my_models'")
|
5
5
|
ActiveRecord::Base.connection.create_table(:my_models) do |t|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
t.string :class
|
7
|
+
t.string :bad_attribute
|
8
|
+
t.string :good_attribute
|
9
9
|
end
|
10
10
|
|
11
11
|
class MyModel < ActiveRecord::Base
|
12
|
-
|
13
|
-
|
12
|
+
include SafeAttributes
|
13
|
+
bad_attribute_names :bad_attribute, :bad_attribute=
|
14
|
+
validates_presence_of :class
|
14
15
|
end
|
15
16
|
|
16
17
|
describe MyModel do
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
19
|
+
before(:each) do
|
20
|
+
ActiveRecord::Base.connection.increment_open_transactions
|
21
|
+
ActiveRecord::Base.connection.begin_db_transaction
|
22
|
+
@model = MyModel.new
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:each) do
|
26
|
+
ActiveRecord::Base.connection.rollback_db_transaction
|
27
|
+
ActiveRecord::Base.connection.decrement_open_transactions
|
28
|
+
end
|
29
|
+
|
30
|
+
it "inspecting class returns expected attribute names" do
|
31
|
+
MyModel.inspect.should match 'class: string'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "inspecting instance returns expected attribute names" do
|
35
|
+
@model.inspect.should match 'class: nil'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "does not redefine class()" do
|
39
|
+
@model.class.name.should == 'MyModel'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "defines class=()" do
|
43
|
+
@model.respond_to?('class=') # to force method generation
|
44
|
+
@model.methods.include?('class=').should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "does not define bad_attribute()" do
|
48
|
+
@model.respond_to?('bad_attribute') # to force method generation
|
49
|
+
@model.methods.include?('bad_attribute').should be_false
|
50
|
+
end
|
51
|
+
|
52
|
+
it "does not define bad_attribute=()" do
|
53
|
+
@model.respond_to?('bad_attribute=') # to force method generation
|
54
|
+
@model.methods.include?('bad_attribute=').should be_false
|
55
|
+
end
|
56
|
+
|
57
|
+
it "does define good_attribute()" do
|
58
|
+
@model.respond_to?('good_attribute') # to force method generation
|
59
|
+
@model.methods.include?('good_attribute').should be_true
|
60
|
+
end
|
61
|
+
|
62
|
+
it "does define good_attribute=()" do
|
63
|
+
@model.respond_to?('good_attribute=') # to force method generation
|
64
|
+
@model.methods.include?('good_attribute=').should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
it "does define id()" do
|
68
|
+
@model.respond_to?('id') # to force method generation
|
69
|
+
@model.methods.include?('id').should be_true
|
70
|
+
end
|
71
|
+
|
72
|
+
it "can create instance in database with special attribute name" do
|
73
|
+
m = MyModel.create(:class => 'Foo')
|
74
|
+
m = MyModel.find(m.id)
|
75
|
+
m[:class].should == 'Foo'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "has class attribute" do
|
79
|
+
MyModel.new().has_attribute?('class').should be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
it "can call class= without error" do
|
83
|
+
m = MyModel.new()
|
84
|
+
m.class = 'Foo'
|
85
|
+
m[:class].should == 'Foo'
|
86
|
+
end
|
87
|
+
|
88
|
+
it "can use finders with attribute" do
|
89
|
+
m = MyModel.find_all_by_class('Foo')
|
90
|
+
m.size.should == 0
|
91
|
+
end
|
92
|
+
|
93
|
+
it "validates presence of class" do
|
94
|
+
@model.valid?.should be_false
|
95
|
+
Array(@model.errors[:class]).include?("can't be blank").should be_true
|
96
|
+
|
97
|
+
m = MyModel.new(:class => 'Foo')
|
98
|
+
m.valid?.should be_true
|
99
|
+
end
|
91
100
|
end
|
92
101
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safe_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 3
|
10
|
+
version: 1.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brian Jones
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01
|
18
|
+
date: 2011-02-01 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|