fortify 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +95 -0
- data/lib/fortify.rb +1 -0
- data/lib/fortify/fortify.rb +52 -0
- data/spec/lib_specs/fortify_spec.rb +62 -0
- data/spec/spec_helper.rb +3 -0
- metadata +67 -0
data/README.rdoc
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
=Introduction
|
2
|
+
|
3
|
+
Know how you can't just use 'form_for' in rails with a newly initialized ActiveResource object?
|
4
|
+
Ever get annoyed at having to add default attributes to your newly initialized ActiveResource objects?
|
5
|
+
Fortify gives you the power to DRY'ly define default attributes for your ActiveResource derived classes.
|
6
|
+
|
7
|
+
== Motivation
|
8
|
+
|
9
|
+
Let's suppose you're going to create a form for creating Books. However, your Book is an ActiveResource::Base derived class:
|
10
|
+
|
11
|
+
# app/models/book.rb
|
12
|
+
class Book < ActiveResource::Base
|
13
|
+
end
|
14
|
+
|
15
|
+
# app/controllers/books_controller.rb
|
16
|
+
class BooksController < ActiveResource::Base
|
17
|
+
def new
|
18
|
+
@book = Book.new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# app/view/books/new.haml
|
23
|
+
- form_for @book do |f|
|
24
|
+
.field
|
25
|
+
= f.label :title
|
26
|
+
= f.text_field :title
|
27
|
+
|
28
|
+
.field
|
29
|
+
= f.label :author
|
30
|
+
= f.text_field :author
|
31
|
+
|
32
|
+
.field
|
33
|
+
= f.label :genre
|
34
|
+
= f.text_field :genre
|
35
|
+
|
36
|
+
|
37
|
+
This, of course fails. Why? When you create a new Book object, unlike ActiveRecord (which has the luxury of querying the database to
|
38
|
+
determine the object's attributes), ActiveResource starts off as a blank slate. In other words:
|
39
|
+
|
40
|
+
console> b = Book.new
|
41
|
+
console> b.attributes.inspect
|
42
|
+
==> {}
|
43
|
+
|
44
|
+
|
45
|
+
To get this to work, you would have to give your new Book object some default attributes:
|
46
|
+
|
47
|
+
# app/controllers/books_controller.rb
|
48
|
+
class BooksController < ActiveResource::Base
|
49
|
+
def new
|
50
|
+
@book = Book.new :title => nil, :author => nil, :genre => nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
As you can imagine, this approach might not be very DRY. This is where *fortify* steps in.
|
55
|
+
|
56
|
+
== Usage
|
57
|
+
|
58
|
+
First, install fortify by adding the following line to your config/environment.rb and then running "sudo rake gems:install":
|
59
|
+
|
60
|
+
config.gem :fortify, :lib => 'fortify', :source => 'http://gemcutter.org'
|
61
|
+
|
62
|
+
Next, go back to your book model and add some fortification to it:
|
63
|
+
|
64
|
+
# app/models/book.rb
|
65
|
+
class Book < ActiveResource::Base
|
66
|
+
fortify do |default_attributes|
|
67
|
+
default_attributes.author
|
68
|
+
default_attributes.title
|
69
|
+
default_attributes.genre
|
70
|
+
end
|
71
|
+
self.site = ''
|
72
|
+
end
|
73
|
+
|
74
|
+
Now, your controller / views as you originally specified them will work, since now:
|
75
|
+
|
76
|
+
console> b = Book.new
|
77
|
+
console> b.attributes.inspect
|
78
|
+
==> {:author => nil, :title => nil, :genre => nil}
|
79
|
+
|
80
|
+
You could also have provided some default values for your attributes:
|
81
|
+
|
82
|
+
# app/models/book.rb
|
83
|
+
class Book < ActiveResource::Base
|
84
|
+
fortify do |default_attributes|
|
85
|
+
default_attributes.author = 'Anonymous'
|
86
|
+
default_attributes.title = 'Untitled'
|
87
|
+
default_attributes.genre
|
88
|
+
end
|
89
|
+
self.site = ''
|
90
|
+
end
|
91
|
+
|
92
|
+
In this case, a Book.new would give you:
|
93
|
+
console> b = Book.new
|
94
|
+
console> b.attributes.inspect
|
95
|
+
==> {:author => 'Anonymous', :title => 'Untitled', :genre => nil}
|
data/lib/fortify.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'fortify/fortify'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
ActiveResource::Base.instance_eval do
|
2
|
+
class DefaultAttributes
|
3
|
+
attr_accessor :attributes
|
4
|
+
|
5
|
+
# Override method_missing to allow setting
|
6
|
+
# the default attributes via undefined methods.
|
7
|
+
# For example:
|
8
|
+
# d = DefaultAttributes.new
|
9
|
+
# d.author = 'Anonymous'
|
10
|
+
# puts d.author # returns "Anonymous"
|
11
|
+
# puts d.attributes[:author] # returns "Anonymous"
|
12
|
+
def method_missing(method, *args, &block)
|
13
|
+
k = attribute_name(method)
|
14
|
+
v = method.to_s[-1..-1] == '=' ? args[0] : nil
|
15
|
+
attributes[k] = v
|
16
|
+
end
|
17
|
+
|
18
|
+
def attributes
|
19
|
+
@attributes ||= HashWithIndifferentAccess.new
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
# strip the trailing "=" from a missing_method call
|
24
|
+
def attribute_name(attribute_method_call)
|
25
|
+
name = attribute_method_call.to_s
|
26
|
+
name[-1..-1] == '=' ? name[0..-2] : name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class BlockRequiredError < ArgumentError; end
|
31
|
+
|
32
|
+
class BlockArgumentError < ArgumentError; end
|
33
|
+
|
34
|
+
|
35
|
+
def fortify(&block)
|
36
|
+
raise BlockRequiredError.new("you must pass a block to fortify") unless block
|
37
|
+
raise BlockArgumentError.new("the block you pass to fortify must accept one argument") unless block.arity == 1
|
38
|
+
block.call default_attributes
|
39
|
+
end
|
40
|
+
|
41
|
+
def default_attributes
|
42
|
+
@default_attributes ||= DefaultAttributes.new
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
ActiveResource::Base.class_eval do
|
47
|
+
def initialize_with_default_attributes(attributes={})
|
48
|
+
initialize_without_default_attributes self.class.default_attributes.attributes.merge(attributes)
|
49
|
+
end
|
50
|
+
|
51
|
+
alias_method_chain :initialize, :default_attributes
|
52
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "ActiveResource::Base --" do
|
4
|
+
before do
|
5
|
+
class Book < ActiveResource::Base
|
6
|
+
self.site = ''
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "default_attributes class method" do
|
11
|
+
it "should return a DefaultAttributes class" do
|
12
|
+
Book.default_attributes.class.to_s.should == "DefaultAttributes"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "DefaultAttributes" do
|
17
|
+
it "should have an attributes accessor" do
|
18
|
+
proc {Book.default_attributes.attributes}.should_not raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should support setting attributes via method missing" do
|
22
|
+
proc {Book.default_attributes.author}.should_not raise_error
|
23
|
+
Book.default_attributes.attributes.has_key?(:author).should be_true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "fortify class method" do
|
28
|
+
it "should require a block be passed to it" do
|
29
|
+
proc { Book.fortify }.should raise_error(BlockRequiredError)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should require the block passed to it accept one argument" do
|
33
|
+
proc { Book.fortify {} }.should raise_error(BlockArgumentError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should pass a default attributes class to the block" do
|
37
|
+
Book.fortify do |default_attributes|
|
38
|
+
default_attributes.class.to_s.should == "DefaultAttributes"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "new" do
|
44
|
+
it "should use the default attributes created via fortify" do
|
45
|
+
Book.fortify do |default_attributes|
|
46
|
+
default_attributes.author = 'Anonymous'
|
47
|
+
default_attributes.genre = 'Fiction'
|
48
|
+
default_attributes.isbn
|
49
|
+
end
|
50
|
+
|
51
|
+
b = Book.new
|
52
|
+
|
53
|
+
proc {b.author}.should_not raise_error
|
54
|
+
b.author.should == 'Anonymous'
|
55
|
+
proc {b.genre}.should_not raise_error
|
56
|
+
b.genre.should == 'Fiction'
|
57
|
+
proc {b.isbn}.should_not raise_error
|
58
|
+
b.isbn.should be_nil
|
59
|
+
proc {b.attribute_not_appearing_in_this_test}.should raise_error
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fortify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Parker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-11 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.3.3
|
24
|
+
version:
|
25
|
+
description: Know how you can't just use 'form_for' in rails with a newly initialized ActiveResource object? Ever get annoyed at having to add default attributes to your newly initialized ActiveResource objects? Fortify gives you the power to DRY'ly define default attributes for your ActiveResource derived classes.
|
26
|
+
email: moonmaster9000@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
files:
|
34
|
+
- README.rdoc
|
35
|
+
- lib/fortify.rb
|
36
|
+
- lib/fortify/fortify.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/moonmaster9000/fortify
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.3.5
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: Default attributes for your ActiveResource objects
|
65
|
+
test_files:
|
66
|
+
- spec/lib_specs/fortify_spec.rb
|
67
|
+
- spec/spec_helper.rb
|