fortify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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}
@@ -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
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH << './lib'
2
+ require 'activeresource'
3
+ require 'fortify'
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