active_presenter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README +75 -0
- data/Rakefile +19 -0
- data/lib/active_presenter.rb +7 -0
- data/lib/active_presenter/base.rb +165 -0
- data/lib/active_presenter/version.rb +9 -0
- data/lib/tasks/gem.rake +62 -0
- data/test/base_test.rb +142 -0
- data/test/test_helper.rb +32 -0
- metadata +63 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2008 Daniel Haran, James Golick, GiraffeSoft, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
= ActivePresenter
|
2
|
+
|
3
|
+
ActivePresenter is the presenter library you already know! (...if you know ActiveRecord)
|
4
|
+
|
5
|
+
By acting nearly identically to ActiveRecord models, ActivePresenter makes presenters highly approachable to anybody who is already familiar with ActiveRecord.
|
6
|
+
|
7
|
+
== Get It
|
8
|
+
|
9
|
+
As a gem:
|
10
|
+
|
11
|
+
$ sudo gem install active_presenter
|
12
|
+
|
13
|
+
As a rails gem dependency:
|
14
|
+
|
15
|
+
config.gem 'active_presenter'
|
16
|
+
|
17
|
+
Or get the source from github:
|
18
|
+
|
19
|
+
$ git clone git://github.com/giraffesoft/active_presenter.git
|
20
|
+
|
21
|
+
(or fork it at http://github.com/giraffesoft/active_presenter)
|
22
|
+
|
23
|
+
== Usage
|
24
|
+
|
25
|
+
Creating a presenter is as simple as subclassing ActivePresenter::Base. Use the presents method to indicate which models the presenter should present.
|
26
|
+
|
27
|
+
class SignupPresenter < ActivePresenter::Base
|
28
|
+
presents User, Account
|
29
|
+
end
|
30
|
+
|
31
|
+
=== Instantiation
|
32
|
+
|
33
|
+
Then, you can instantiate the presenter using either, or both of two forms.
|
34
|
+
|
35
|
+
For example, if you had a SignupPresenter that presented User, and Account, you could specify arguments in the following two forms:
|
36
|
+
|
37
|
+
1. SignupPresenter.new(:user_login => 'james', :user_password => 'swordfish', :user_password_confirmation => 'swordfish', :account_subdomain => 'giraffesoft')
|
38
|
+
|
39
|
+
- This form is useful for initializing a new presenter from the params hash: i.e. SignupPresenter.new(params[:signup_presenter])
|
40
|
+
|
41
|
+
2. SignupPresenter.new(:user => User.find(1), :account => Account.find(2))
|
42
|
+
|
43
|
+
- This form is useful if you have instances that you'd like to edit using the presenter. You can subsequently call presenter.update_attributes(params[:signup_presenter]) just like with a regular AR instance.
|
44
|
+
|
45
|
+
Both forms can also be mixed together: SignupPresenter.new(:user => User.find(1), :user_login => 'james').
|
46
|
+
|
47
|
+
In this case, the login attribute will be updated on the user instance provided.
|
48
|
+
|
49
|
+
If you don't specify an instance, one will be created by calling Model.new
|
50
|
+
|
51
|
+
=== Validation
|
52
|
+
|
53
|
+
The #valid? method will return true or false based on the validity of the presented objects.
|
54
|
+
|
55
|
+
This is calculated by calling #valid? on them.
|
56
|
+
|
57
|
+
You can retrieve the errors in two ways.
|
58
|
+
|
59
|
+
1. By calling #errors on the presenter, which returns an instance of ActiveRecord::Errors where all the attributes are in type_name_attribute_name form (i.e. You'd retrieve an error on User#login, by calling @presenter.errors.on(:user_login)).
|
60
|
+
|
61
|
+
2. By calling @presenter.user_errors, or @presenter.user.errors to retrieve the errors from one presentable.
|
62
|
+
|
63
|
+
Both of these methods are compatible with error_messages_for. It just depends whether you'd like to show all the errors in one block, or whether you'd prefer to break them up.
|
64
|
+
|
65
|
+
=== Saving
|
66
|
+
|
67
|
+
You can save your presenter the same way you'd save an ActiveRecord object. Both #save, and #save! behave the same way they do on a normal AR model.
|
68
|
+
|
69
|
+
== Credits
|
70
|
+
|
71
|
+
ActivePresenter was created, and is maintained by {Daniel Haran}[http://danielharan.com] and {James Golick}[http://jamesgolick.com] on the train ride to {RubyFringe}[http://rubyfringe.com] from Montreal.
|
72
|
+
|
73
|
+
== License
|
74
|
+
|
75
|
+
ActivePresenter is available under the {MIT License}[http://en.wikipedia.org/wiki/MIT_License]
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require File.dirname(__FILE__)+'/lib/active_presenter'
|
4
|
+
Dir.glob(File.dirname(__FILE__)+'/lib/tasks/**/*.rake').each { |l| load l }
|
5
|
+
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
task :test do
|
9
|
+
Dir['test/**/*_test.rb'].each { |l| require l }
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Generate documentation for the ResourceController plugin.'
|
13
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
14
|
+
rdoc.rdoc_dir = 'rdoc'
|
15
|
+
rdoc.title = 'ActivePresenter'
|
16
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
17
|
+
rdoc.rdoc_files.include('README')
|
18
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
19
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module ActivePresenter
|
2
|
+
# Base class for presenters. See README for usage.
|
3
|
+
#
|
4
|
+
class Base
|
5
|
+
class_inheritable_accessor :presented
|
6
|
+
self.presented = {}
|
7
|
+
|
8
|
+
# Indicates which models are to be presented by this presenter.
|
9
|
+
# i.e.
|
10
|
+
#
|
11
|
+
# class SignupPresenter < ActivePresenter::Base
|
12
|
+
# presents User, Account
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
#
|
16
|
+
def self.presents(*types)
|
17
|
+
attr_accessor *types
|
18
|
+
|
19
|
+
types.each do |t|
|
20
|
+
define_method("#{t}_errors") do
|
21
|
+
send(t).errors
|
22
|
+
end
|
23
|
+
|
24
|
+
presented[t] = t.to_s.classify.constantize
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.human_attribute_name(attribute_name)
|
29
|
+
presentable_type = presented.keys.detect do |type|
|
30
|
+
attribute_name.to_s.starts_with?("#{type}_")
|
31
|
+
end
|
32
|
+
|
33
|
+
attribute_name.to_s.gsub("#{presentable_type}_", "").humanize
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_accessor :errors
|
37
|
+
|
38
|
+
# Accepts arguments in two forms. For example, if you had a SignupPresenter that presented User, and Account, you could specify arguments in the following two forms:
|
39
|
+
#
|
40
|
+
# 1. SignupPresenter.new(:user_login => 'james', :user_password => 'swordfish', :user_password_confirmation => 'swordfish', :account_subdomain => 'giraffesoft')
|
41
|
+
# - This form is useful for initializing a new presenter from the params hash: i.e. SignupPresenter.new(params[:signup_presenter])
|
42
|
+
# 2. SignupPresenter.new(:user => User.find(1), :account => Account.find(2))
|
43
|
+
# - This form is useful if you have instances that you'd like to edit using the presenter. You can subsequently call presenter.update_attributes(params[:signup_presenter]) just like with a regular AR instance.
|
44
|
+
#
|
45
|
+
# Both forms can also be mixed together: SignupPresenter.new(:user => User.find(1), :user_login => 'james')
|
46
|
+
# In this case, the login attribute will be updated on the user instance provided.
|
47
|
+
#
|
48
|
+
# If you don't specify an instance, one will be created by calling Model.new
|
49
|
+
#
|
50
|
+
def initialize(args = {})
|
51
|
+
presented.each do |type, klass|
|
52
|
+
send("#{type}=", args[type].is_a?(klass) ? args.delete(type) : klass.new)
|
53
|
+
end
|
54
|
+
|
55
|
+
self.attributes = args
|
56
|
+
end
|
57
|
+
|
58
|
+
# Set the attributes of the presentable instances using the type_attribute form (i.e. user_login => 'james')
|
59
|
+
#
|
60
|
+
def attributes=(attrs)
|
61
|
+
attrs.each { |k,v| send("#{k}=", v) }
|
62
|
+
end
|
63
|
+
|
64
|
+
# Makes sure that the presenter is accurate about responding to presentable's attributes, even though they are handled by method_missing.
|
65
|
+
#
|
66
|
+
def respond_to?(method)
|
67
|
+
presented_attribute?(method) || super
|
68
|
+
end
|
69
|
+
|
70
|
+
# Handles the decision about whether to delegate getters and setters to presentable instances.
|
71
|
+
#
|
72
|
+
def method_missing(method_name, *args, &block)
|
73
|
+
presented_attribute?(method_name) ? delegate_message(method_name, *args, &block) : super
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns an instance of ActiveRecord::Errors with all the errors from the presentables merged in using the type_attribute form (i.e. user_login).
|
77
|
+
#
|
78
|
+
def errors
|
79
|
+
@errors ||= ActiveRecord::Errors.new(self)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns boolean based on the validity of the presentables by calling valid? on each of them.
|
83
|
+
#
|
84
|
+
def valid?
|
85
|
+
presented.keys.each do |type|
|
86
|
+
presented_inst = send(type)
|
87
|
+
|
88
|
+
merge_errors(presented_inst, type) unless presented_inst.valid?
|
89
|
+
end
|
90
|
+
|
91
|
+
errors.empty?
|
92
|
+
end
|
93
|
+
|
94
|
+
# Save all of the presentables, wrapped in a transaction.
|
95
|
+
#
|
96
|
+
# Returns true or false based on success.
|
97
|
+
#
|
98
|
+
def save
|
99
|
+
saved = false
|
100
|
+
|
101
|
+
ActiveRecord::Base.transaction do
|
102
|
+
if valid?
|
103
|
+
saved = presented_instances.map { |i| i.save(false) }.all?
|
104
|
+
raise ActiveRecord::Rollback unless saved # TODO: Does this happen implicitly?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
saved
|
109
|
+
end
|
110
|
+
|
111
|
+
# Save all of the presentables, by calling each of their save! methods, wrapped in a transaction.
|
112
|
+
#
|
113
|
+
# Returns true on success, will raise otherwise.
|
114
|
+
#
|
115
|
+
def save!
|
116
|
+
ActiveRecord::Base.transaction do
|
117
|
+
valid? # collect errors before potential exception raise
|
118
|
+
presented_instances.each { |i| i.save! }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Update attributes, and save the presentables
|
123
|
+
#
|
124
|
+
# Returns true or false based on success.
|
125
|
+
#
|
126
|
+
def update_attributes(attrs)
|
127
|
+
self.attributes = attrs
|
128
|
+
save
|
129
|
+
end
|
130
|
+
|
131
|
+
protected
|
132
|
+
def presented_instances
|
133
|
+
presented.keys.map { |key| send(key) }
|
134
|
+
end
|
135
|
+
|
136
|
+
def delegate_message(method_name, *args, &block)
|
137
|
+
presentable = presentable_for(method_name)
|
138
|
+
send(presentable).send(flatten_attribute_name(method_name, presentable), *args, &block)
|
139
|
+
end
|
140
|
+
|
141
|
+
def presentable_for(method_name)
|
142
|
+
presented.keys.detect do |type|
|
143
|
+
method_name.to_s.starts_with?(attribute_prefix(type))
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def presented_attribute?(method_name)
|
148
|
+
!presentable_for(method_name).nil?
|
149
|
+
end
|
150
|
+
|
151
|
+
def flatten_attribute_name(name, type)
|
152
|
+
name.to_s.gsub(/^#{attribute_prefix(type)}/, '')
|
153
|
+
end
|
154
|
+
|
155
|
+
def attribute_prefix(type)
|
156
|
+
"#{type}_"
|
157
|
+
end
|
158
|
+
|
159
|
+
def merge_errors(presented_inst, type)
|
160
|
+
presented_inst.errors.each do |att,msg|
|
161
|
+
errors.add(attribute_prefix(type)+att, msg)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
data/lib/tasks/gem.rake
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rake/gempackagetask'
|
2
|
+
|
3
|
+
task :clean => :clobber_package
|
4
|
+
|
5
|
+
spec = Gem::Specification.new do |s|
|
6
|
+
s.name = ActivePresenter::NAME
|
7
|
+
s.version = ActivePresenter::VERSION::STRING
|
8
|
+
s.summary =
|
9
|
+
s.description = "ActivePresenter is the presenter library you already know! (...if you know ActiveRecord)"
|
10
|
+
s.author = "James Golick & Daniel Haran"
|
11
|
+
s.email = 'james@giraffesoft.ca'
|
12
|
+
s.homepage = 'http://jamesgolick.com/active_presenter'
|
13
|
+
s.rubyforge_project = 'active_presenter'
|
14
|
+
s.has_rdoc = true
|
15
|
+
|
16
|
+
s.required_ruby_version = '>= 1.8.5'
|
17
|
+
|
18
|
+
s.files = %w(README LICENSE Rakefile) +
|
19
|
+
Dir.glob("{lib,test}/**/*")
|
20
|
+
|
21
|
+
s.require_path = "lib"
|
22
|
+
end
|
23
|
+
|
24
|
+
Rake::GemPackageTask.new(spec) do |p|
|
25
|
+
p.gem_spec = spec
|
26
|
+
end
|
27
|
+
|
28
|
+
task :tag_warn do
|
29
|
+
puts "*" * 40
|
30
|
+
puts "Don't forget to tag the release:"
|
31
|
+
puts
|
32
|
+
puts " git tag -a v#{ActivePresenter::VERSION::STRING}"
|
33
|
+
puts
|
34
|
+
puts "or run rake tag"
|
35
|
+
puts "*" * 40
|
36
|
+
end
|
37
|
+
|
38
|
+
task :tag do
|
39
|
+
sh "git tag -a v#{ActivePresenter::VERSION::STRING}"
|
40
|
+
end
|
41
|
+
task :gem => :tag_warn
|
42
|
+
|
43
|
+
namespace :gem do
|
44
|
+
namespace :upload do
|
45
|
+
|
46
|
+
desc 'Upload gems (ruby & win32) to rubyforge.org'
|
47
|
+
task :rubyforge => :gem do
|
48
|
+
sh 'rubyforge login'
|
49
|
+
sh "rubyforge add_release giraffesoft active_presenter #{ActivePresenter::VERSION::STRING} pkg/#{spec.full_name}.gem"
|
50
|
+
sh "rubyforge add_file giraffesoft active_presenter #{ActivePresenter::VERSION::STRING} pkg/#{spec.full_name}.gem"
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
task :install => [:clobber, :package] do
|
57
|
+
sh "sudo gem install pkg/#{spec.full_name}.gem"
|
58
|
+
end
|
59
|
+
|
60
|
+
task :uninstall => :clean do
|
61
|
+
sh "sudo gem uninstall -v #{ActivePresenter::VERSION::STRING} -x #{ActivePresenter::NAME}"
|
62
|
+
end
|
data/test/base_test.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/test_helper'
|
2
|
+
|
3
|
+
Expectations do
|
4
|
+
expect :user => User, :account => Account do
|
5
|
+
SignupPresenter.presented
|
6
|
+
end
|
7
|
+
|
8
|
+
expect User.create!(hash_for_user) do |u|
|
9
|
+
SignupPresenter.new(:user => u.expected).user
|
10
|
+
end
|
11
|
+
|
12
|
+
expect User do
|
13
|
+
SignupPresenter.new.user
|
14
|
+
end
|
15
|
+
|
16
|
+
expect User.any_instance.to.receive(:login=).with('james') do
|
17
|
+
SignupPresenter.new(:user_login => 'james')
|
18
|
+
end
|
19
|
+
|
20
|
+
expect 'mymockvalue' do
|
21
|
+
User.any_instance.stubs(:login).returns('mymockvalue')
|
22
|
+
SignupPresenter.new.user_login
|
23
|
+
end
|
24
|
+
|
25
|
+
expect User.any_instance.to.receive(:login=).with('mymockvalue') do
|
26
|
+
SignupPresenter.new.user_login = 'mymockvalue'
|
27
|
+
end
|
28
|
+
|
29
|
+
expect SignupPresenter.new.not.to.be.valid?
|
30
|
+
expect SignupPresenter.new(:user => User.new(hash_for_user)).to.be.valid?
|
31
|
+
|
32
|
+
expect ActiveRecord::Errors do
|
33
|
+
s = SignupPresenter.new
|
34
|
+
s.valid?
|
35
|
+
s.errors
|
36
|
+
end
|
37
|
+
|
38
|
+
expect ActiveRecord::Errors do
|
39
|
+
s = SignupPresenter.new
|
40
|
+
s.valid?
|
41
|
+
s.user_errors
|
42
|
+
end
|
43
|
+
|
44
|
+
expect ActiveRecord::Errors do
|
45
|
+
s = SignupPresenter.new
|
46
|
+
s.valid?
|
47
|
+
s.account_errors
|
48
|
+
end
|
49
|
+
|
50
|
+
expect String do
|
51
|
+
s = SignupPresenter.new
|
52
|
+
s.valid?
|
53
|
+
s.errors.on(:user_login)
|
54
|
+
end
|
55
|
+
|
56
|
+
expect ActiveRecord::Base.to.receive(:transaction) do
|
57
|
+
s = SignupPresenter.new
|
58
|
+
s.save
|
59
|
+
end
|
60
|
+
|
61
|
+
expect User.any_instance.to.receive(:save) do
|
62
|
+
s = SignupPresenter.new :user => User.new(hash_for_user)
|
63
|
+
s.save
|
64
|
+
end
|
65
|
+
|
66
|
+
expect Account.any_instance.to.receive(:save) do
|
67
|
+
s = SignupPresenter.new :user => User.new(hash_for_user)
|
68
|
+
s.save
|
69
|
+
end
|
70
|
+
|
71
|
+
expect SignupPresenter.new.not.to.be.save
|
72
|
+
|
73
|
+
expect ActiveRecord::Rollback do
|
74
|
+
ActiveRecord::Base.stubs(:transaction).yields
|
75
|
+
User.any_instance.stubs(:save).returns(false)
|
76
|
+
Account.any_instance.stubs(:save).returns(false)
|
77
|
+
s = SignupPresenter.new :user => User.new(hash_for_user)
|
78
|
+
s.save
|
79
|
+
end
|
80
|
+
|
81
|
+
expect ActiveRecord::Base.to.receive(:transaction) do
|
82
|
+
s = SignupPresenter.new
|
83
|
+
s.save!
|
84
|
+
end
|
85
|
+
|
86
|
+
expect User.any_instance.to.receive(:save!) do
|
87
|
+
s = SignupPresenter.new
|
88
|
+
s.save!
|
89
|
+
end
|
90
|
+
|
91
|
+
expect Account.any_instance.to.receive(:save!) do
|
92
|
+
User.any_instance.stubs(:save!)
|
93
|
+
s = SignupPresenter.new
|
94
|
+
s.save!
|
95
|
+
end
|
96
|
+
|
97
|
+
expect ActiveRecord::RecordInvalid do
|
98
|
+
SignupPresenter.new.save!
|
99
|
+
end
|
100
|
+
|
101
|
+
expect SignupPresenter.new(:user => User.new(hash_for_user)).to.be.save!
|
102
|
+
|
103
|
+
expect SignupPresenter.new.to.be.respond_to?(:user_login)
|
104
|
+
expect SignupPresenter.new.to.be.respond_to?(:valid?) # just making sure i didn't break everything :)
|
105
|
+
|
106
|
+
expect User.create!(hash_for_user).not.to.be.login_changed? do |user|
|
107
|
+
s = SignupPresenter.new(:user => user)
|
108
|
+
s.update_attributes :user_login => 'Something Totally Different'
|
109
|
+
end
|
110
|
+
|
111
|
+
expect SignupPresenter.new(:user => User.create!(hash_for_user)).to.receive(:save) do |s|
|
112
|
+
s.update_attributes :user_login => 'Something'
|
113
|
+
end
|
114
|
+
|
115
|
+
expect 'Something Different' do
|
116
|
+
s = SignupPresenter.new
|
117
|
+
s.update_attributes :user_login => 'Something Different'
|
118
|
+
s.user_login
|
119
|
+
end
|
120
|
+
|
121
|
+
# this is a regression test to make sure that _title is working. we had a weird conflict with using String#delete
|
122
|
+
expect 'something' do
|
123
|
+
s = SignupPresenter.new :account_title => 'something'
|
124
|
+
s.account_title
|
125
|
+
end
|
126
|
+
|
127
|
+
expect String do
|
128
|
+
s = SignupPresenter.new
|
129
|
+
s.save
|
130
|
+
s.errors.on(:user_login)
|
131
|
+
end
|
132
|
+
|
133
|
+
expect String do
|
134
|
+
s = SignupPresenter.new
|
135
|
+
s.save! rescue
|
136
|
+
s.errors.on(:user_login)
|
137
|
+
end
|
138
|
+
|
139
|
+
expect 'Login' do
|
140
|
+
SignupPresenter.human_attribute_name(:user_login)
|
141
|
+
end
|
142
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../lib/active_presenter'
|
2
|
+
require 'expectations'
|
3
|
+
|
4
|
+
ActiveRecord::Base.configurations = {'sqlite3' => {:adapter => 'sqlite3', :database => ':memory:'}}
|
5
|
+
ActiveRecord::Base.establish_connection('sqlite3')
|
6
|
+
|
7
|
+
ActiveRecord::Schema.define(:version => 0) do
|
8
|
+
create_table :users do |t|
|
9
|
+
t.boolean :admin, :default => false
|
10
|
+
t.string :login, :default => ''
|
11
|
+
t.string :password, :default => ''
|
12
|
+
end
|
13
|
+
|
14
|
+
create_table :accounts do |t|
|
15
|
+
t.string :subdomain, :default => ''
|
16
|
+
t.string :title, :default => ''
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class User < ActiveRecord::Base
|
21
|
+
validates_presence_of :login, :password
|
22
|
+
end
|
23
|
+
class Account < ActiveRecord::Base; end
|
24
|
+
|
25
|
+
class SignupPresenter < ActivePresenter::Base
|
26
|
+
presents :account, :user
|
27
|
+
end
|
28
|
+
|
29
|
+
def hash_for_user(opts = {})
|
30
|
+
{:login => 'jane', :password => 'seekrit' }.merge(opts)
|
31
|
+
end
|
32
|
+
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_presenter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Golick & Daniel Haran
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-07-27 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: ActivePresenter is the presenter library you already know! (...if you know ActiveRecord)
|
17
|
+
email: james@giraffesoft.ca
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- README
|
26
|
+
- LICENSE
|
27
|
+
- Rakefile
|
28
|
+
- lib/active_presenter
|
29
|
+
- lib/active_presenter/base.rb
|
30
|
+
- lib/active_presenter/version.rb
|
31
|
+
- lib/active_presenter.rb
|
32
|
+
- lib/tasks
|
33
|
+
- lib/tasks/gem.rake
|
34
|
+
- test/base_test.rb
|
35
|
+
- test/test_helper.rb
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://jamesgolick.com/active_presenter
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.8.5
|
48
|
+
version:
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project: active_presenter
|
58
|
+
rubygems_version: 1.1.1
|
59
|
+
signing_key:
|
60
|
+
specification_version: 2
|
61
|
+
summary: ActivePresenter is the presenter library you already know! (...if you know ActiveRecord)
|
62
|
+
test_files: []
|
63
|
+
|