active_presenter 1.4.0 → 2.0.0a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -28,7 +28,7 @@ Creating a presenter is as simple as subclassing ActivePresenter::Base. Use the
28
28
  presents :user, :account
29
29
  end
30
30
 
31
- In the above example, :user will (predictably) become User. If you want to override this behaviour, specify the desired types in a hash, as so:
31
+ In the above example, :user will (predictably) become User. If you want to override this behavior, specify the desired types in a hash, as so:
32
32
 
33
33
  class PresenterWithTwoAddresses < ActivePresenter::Base
34
34
  presents :primary_address => Address, :secondary_address => Address
@@ -68,6 +68,15 @@ You can retrieve the errors in two ways.
68
68
 
69
69
  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.
70
70
 
71
+ === Protected and Accessible Attributes
72
+
73
+ ActivePresenter supports +attr_protected+ and +attr_accessible+ just like an ActiveRecord object to avoid mass assignment. This can be leveraged to provide an additional layer of protection at the presenter level.
74
+
75
+ class AccountPresenter < ActivePresenter::Base
76
+ presents :user, :profile
77
+ attr_accessible :user_email, :profile_birthday
78
+ end
79
+
71
80
  === Saving
72
81
 
73
82
  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.
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
1
  require 'rake'
2
- require 'rake/rdoctask'
2
+ require 'rdoc/task'
3
3
  require File.dirname(__FILE__)+'/lib/active_presenter'
4
4
  Dir.glob(File.dirname(__FILE__)+'/lib/tasks/**/*.rake').each { |l| load l }
5
5
 
6
6
  task :default => :test
7
7
 
8
8
  task :test do
9
- Dir['test/**/*_test.rb'].each { |l| require l }
9
+ Dir['test/**/*_test.rb'].each { |l| require File.join(File.dirname(__FILE__),l)}
10
10
  end
@@ -2,13 +2,19 @@ module ActivePresenter
2
2
  # Base class for presenters. See README for usage.
3
3
  #
4
4
  class Base
5
- include ActiveSupport::Callbacks
6
- define_callbacks :before_validation, :before_save, :after_save
7
-
5
+ extend ActiveModel::Callbacks
6
+ extend ActiveModel::Naming
7
+ extend ActiveModel::Translation
8
+ include ActiveModel::MassAssignmentSecurity
9
+ include ActiveModel::Conversion
10
+
11
+ attr_reader :errors
12
+
13
+ define_model_callbacks :validation, :save
14
+
8
15
  class_inheritable_accessor :presented
9
- class_inheritable_accessor :attr_protected, :attr_accessible
10
16
  self.presented = {}
11
-
17
+
12
18
  # Indicates which models are to be presented by this presenter.
13
19
  # i.e.
14
20
  #
@@ -27,29 +33,29 @@ module ActivePresenter
27
33
  types.each { |t| types_and_classes[t] = t.to_s.tableize.classify.constantize }
28
34
 
29
35
  attr_accessor *types_and_classes.keys
30
-
36
+
31
37
  types_and_classes.keys.each do |t|
32
38
  define_method("#{t}_errors") do
33
39
  send(t).errors
34
40
  end
35
-
41
+
36
42
  presented[t] = types_and_classes[t]
37
43
  end
38
44
  end
39
-
45
+
40
46
  def self.human_attribute_name(attribute_key_name, options = {})
41
47
  presentable_type = presented.keys.detect do |type|
42
48
  attribute_key_name.to_s.starts_with?("#{type}_") || attribute_key_name.to_s == type.to_s
43
49
  end
44
50
  attribute_key_name_without_class = attribute_key_name.to_s.gsub("#{presentable_type}_", "")
45
-
51
+
46
52
  if presented[presentable_type] and attribute_key_name_without_class != presentable_type.to_s
47
53
  presented[presentable_type].human_attribute_name(attribute_key_name_without_class, options)
48
54
  else
49
55
  I18n.translate(presentable_type, options.merge(:default => presentable_type.to_s.humanize, :scope => [:activerecord, :models]))
50
56
  end
51
57
  end
52
-
58
+
53
59
  # Since ActivePresenter does not descend from ActiveRecord, we need to
54
60
  # mimic some ActiveRecord behavior in order for the ActiveRecord::Errors
55
61
  # object we're using to work properly.
@@ -59,7 +65,7 @@ module ActivePresenter
59
65
  def self.self_and_descendants_from_active_record # :nodoc:
60
66
  [self]
61
67
  end
62
-
68
+
63
69
  def self.human_name(options = {}) # :nodoc:
64
70
  defaults = self_and_descendants_from_active_record.map do |klass|
65
71
  :"#{klass.name.underscore}"
@@ -67,31 +73,7 @@ module ActivePresenter
67
73
  defaults << self.name.humanize
68
74
  I18n.translate(defaults.shift, {:scope => [:activerecord, :models], :count => 1, :default => defaults}.merge(options))
69
75
  end
70
-
71
- # Note that +attr_protected+ is still applied to the received hash. Thus,
72
- # with this technique you can at most _extend_ the list of protected
73
- # attributes for a particular mass-assignment call.
74
- def self.attr_protected(*attributes)
75
- write_inheritable_attribute(:attr_protected, Set.new(attributes.map {|a| a.to_s}) + (protected_attributes || []))
76
- end
77
-
78
- # Returns an array of all the attributes that have been protected from mass-assignment.
79
- def self.protected_attributes # :nodoc:
80
- read_inheritable_attribute(:attr_protected)
81
- end
82
-
83
- # Note that +attr_accessible+ is still applied to the received hash. Thus,
84
- # with this technique you can at most _narrow_ the list of accessible
85
- # attributes for a particular mass-assignment call.
86
- def self.attr_accessible(*attributes)
87
- write_inheritable_attribute(:attr_accessible, Set.new(attributes.map(&:to_s)) + (accessible_attributes || []))
88
- end
89
-
90
- # Returns an array of all the attributes that have been made accessible to mass-assignment.
91
- def self.accessible_attributes # :nodoc:
92
- read_inheritable_attribute(:attr_accessible)
93
- end
94
-
76
+
95
77
  # 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:
96
78
  #
97
79
  # 1. SignupPresenter.new(:user_login => 'james', :user_password => 'swordfish', :user_password_confirmation => 'swordfish', :account_subdomain => 'giraffesoft')
@@ -105,13 +87,12 @@ module ActivePresenter
105
87
  # If you don't specify an instance, one will be created by calling Model.new
106
88
  #
107
89
  def initialize(args = {})
108
- args ||= {}
109
-
90
+ @errors = ActiveModel::Errors.new(self)
91
+ return self unless args
110
92
  presented.each do |type, klass|
111
93
  value = args.delete(type)
112
94
  send("#{type}=", value.is_a?(klass) ? value : klass.new)
113
95
  end
114
-
115
96
  self.attributes = args
116
97
  end
117
98
 
@@ -121,11 +102,11 @@ module ActivePresenter
121
102
  #
122
103
  def attributes=(attrs)
123
104
  return if attrs.nil?
124
-
125
- attrs = attrs.stringify_keys
105
+
106
+ attrs = attrs.stringify_keys
126
107
  multi_parameter_attributes = {}
127
- attrs = remove_attributes_protected_from_mass_assignment(attrs)
128
-
108
+ attrs = sanitize_for_mass_assignment(attrs)
109
+
129
110
  attrs.each do |k,v|
130
111
  if (base_attribute = k.to_s.split("(").first) != k.to_s
131
112
  presentable = presentable_for(base_attribute)
@@ -135,87 +116,79 @@ module ActivePresenter
135
116
  send("#{k}=", v) unless attribute_protected?(k)
136
117
  end
137
118
  end
138
-
119
+
139
120
  multi_parameter_attributes.each do |presentable,multi_attrs|
140
121
  send(presentable).send(:attributes=, multi_attrs)
141
122
  end
142
123
  end
143
-
124
+
144
125
  # Makes sure that the presenter is accurate about responding to presentable's attributes, even though they are handled by method_missing.
145
126
  #
146
127
  def respond_to?(method, include_private = false)
147
128
  presented_attribute?(method) || super
148
129
  end
149
-
130
+
150
131
  # Handles the decision about whether to delegate getters and setters to presentable instances.
151
132
  #
152
133
  def method_missing(method_name, *args, &block)
153
134
  presented_attribute?(method_name) ? delegate_message(method_name, *args, &block) : super
154
135
  end
155
-
156
- # Returns an instance of ActiveRecord::Errors with all the errors from the presentables merged in using the type_attribute form (i.e. user_login).
157
- #
158
- def errors
159
- @errors ||= ActiveRecord::Errors.new(self)
160
- end
161
-
136
+
162
137
  # Returns boolean based on the validity of the presentables by calling valid? on each of them.
163
138
  #
164
139
  def valid?
140
+ validated = false
165
141
  errors.clear
166
- if run_callbacks_with_halt(:before_validation)
142
+ result = _run_validation_callbacks do
167
143
  presented.keys.each do |type|
168
144
  presented_inst = send(type)
169
-
170
145
  next unless save?(type, presented_inst)
171
146
  merge_errors(presented_inst, type) unless presented_inst.valid?
172
147
  end
173
-
174
- errors.empty?
148
+ validated = true
175
149
  end
150
+ errors.empty? && validated
176
151
  end
177
-
152
+
178
153
  # Do any of the attributes have unsaved changes?
179
154
  def changed?
180
155
  presented_instances.map(&:changed?).any?
181
156
  end
182
-
157
+
183
158
  # Save all of the presentables, wrapped in a transaction.
184
159
  #
185
160
  # Returns true or false based on success.
186
161
  #
187
162
  def save
188
163
  saved = false
189
-
190
164
  ActiveRecord::Base.transaction do
191
- if valid? && run_callbacks_with_halt(:before_save)
192
- saved = presented.keys.select {|key| save?(key, send(key))}.all? {|key| send(key).save}
193
- raise ActiveRecord::Rollback unless saved # TODO: Does this happen implicitly?
165
+ if valid?
166
+ _run_save_callbacks do
167
+ saved = presented.keys.select {|key| save?(key, send(key))}.all? {|key| send(key).save}
168
+ raise ActiveRecord::Rollback unless saved
169
+ end
194
170
  end
195
-
196
- run_callbacks_with_halt(:after_save) if saved
197
171
  end
198
-
199
172
  saved
200
173
  end
201
-
174
+
202
175
  # Save all of the presentables wrapped in a transaction.
203
176
  #
204
177
  # Returns true on success, will raise otherwise.
205
178
  #
206
179
  def save!
207
- raise ActiveRecord::RecordInvalid.new(self) unless valid?
208
- raise ActiveRecord::RecordNotSaved unless run_callbacks_with_halt(:before_save)
209
-
180
+ saved = false
210
181
  ActiveRecord::Base.transaction do
211
- presented.keys.select {|key| save?(key, send(key))}.each {|key| send(key).save!}
212
-
213
- run_callbacks_with_halt(:after_save)
182
+ raise ActiveRecord::RecordInvalid.new(self) unless valid?
183
+ _run_save_callbacks do
184
+ presented.keys.select {|key| save?(key, send(key))}.all? {|key| send(key).save!}
185
+ saved = true
186
+ end
187
+ raise ActiveRecord::RecordNotSaved.new(self) unless saved
214
188
  end
215
-
216
- true
189
+ saved
217
190
  end
218
-
191
+
219
192
  # Update attributes, and save the presentables
220
193
  #
221
194
  # Returns true or false based on success.
@@ -224,7 +197,7 @@ module ActivePresenter
224
197
  self.attributes = attrs
225
198
  save
226
199
  end
227
-
200
+
228
201
  # Should this presented instance be saved? By default, this returns true
229
202
  # Called from #save and #save!
230
203
  #
@@ -244,72 +217,61 @@ module ActivePresenter
244
217
  def id # :nodoc:
245
218
  nil
246
219
  end
247
-
220
+
248
221
  def new_record?
249
- true
222
+ presented_instances.map(&:new_record?).all?
223
+ end
224
+
225
+ def persisted?
226
+ presented_instances.map(&:persisted?).all?
250
227
  end
251
228
 
252
229
  protected
253
- def presented_instances
254
- presented.keys.map { |key| send(key) }
255
- end
256
-
257
- def delegate_message(method_name, *args, &block)
258
- presentable = presentable_for(method_name)
259
- send(presentable).send(flatten_attribute_name(method_name, presentable), *args, &block)
260
- end
261
-
262
- def presentable_for(method_name)
263
- presented.keys.sort_by { |k| k.to_s.size }.reverse.detect do |type|
264
- method_name.to_s.starts_with?(attribute_prefix(type))
265
- end
266
- end
267
-
268
- def presented_attribute?(method_name)
269
- p = presentable_for(method_name)
270
- !p.nil? && send(p).respond_to?(flatten_attribute_name(method_name,p))
271
- end
272
-
273
- def flatten_attribute_name(name, type)
274
- name.to_s.gsub(/^#{attribute_prefix(type)}/, '')
275
- end
276
-
277
- def attribute_prefix(type)
278
- "#{type}_"
279
- end
280
-
281
- def merge_errors(presented_inst, type)
282
- presented_inst.errors.each do |att,msg|
283
- if att == 'base'
284
- errors.add(type, msg)
285
- else
286
- errors.add(attribute_prefix(type)+att, msg)
287
- end
288
- end
289
- end
290
-
291
- def attribute_protected?(name)
292
- presentable = presentable_for(name)
293
- return false unless presentable
294
- flat_attribute = {flatten_attribute_name(name, presentable) => ''} #remove_att... normally takes a hash, so we use a ''
295
- presented[presentable].new.send(:remove_attributes_protected_from_mass_assignment, flat_attribute).empty?
296
- end
297
-
298
- def run_callbacks_with_halt(callback)
299
- run_callbacks(callback) { |result, object| result == false }
230
+
231
+ def presented_instances
232
+ presented.keys.map { |key| send(key) }
233
+ end
234
+
235
+ def delegate_message(method_name, *args, &block)
236
+ presentable = presentable_for(method_name)
237
+ send(presentable).send(flatten_attribute_name(method_name, presentable), *args, &block)
238
+ end
239
+
240
+ def presentable_for(method_name)
241
+ presented.keys.sort_by { |k| k.to_s.size }.reverse.detect do |type|
242
+ method_name.to_s.starts_with?(attribute_prefix(type))
300
243
  end
301
-
302
- def remove_attributes_protected_from_mass_assignment(attributes)
303
- if self.class.accessible_attributes.nil? && self.class.protected_attributes.nil?
304
- attributes
305
- elsif self.class.protected_attributes.nil?
306
- attributes.reject { |key, value| !self.class.accessible_attributes.include?(key.gsub(/\(.+/, ""))}
307
- elsif self.class.accessible_attributes.nil?
308
- attributes.reject { |key, value| self.class.protected_attributes.include?(key.gsub(/\(.+/,""))}
244
+ end
245
+
246
+ def presented_attribute?(method_name)
247
+ p = presentable_for(method_name)
248
+ !p.nil? && send(p).respond_to?(flatten_attribute_name(method_name,p))
249
+ end
250
+
251
+ def flatten_attribute_name(name, type)
252
+ name.to_s.gsub(/^#{attribute_prefix(type)}/, '')
253
+ end
254
+
255
+ def attribute_prefix(type)
256
+ "#{type}_"
257
+ end
258
+
259
+ def merge_errors(presented_inst, type)
260
+ presented_inst.errors.each do |att,msg|
261
+ if att == :base
262
+ errors.add(type, msg)
309
263
  else
310
- raise "Declare either attr_protected or attr_accessible for #{self.class}, but not both."
264
+ errors.add(attribute_prefix(type)+att.to_s, msg)
311
265
  end
312
266
  end
313
-
267
+ end
268
+
269
+ def attribute_protected?(name)
270
+ presentable = presentable_for(name)
271
+ return false unless presentable
272
+ flat_attribute = {flatten_attribute_name(name, presentable) => ''} #remove_att... normally takes a hash, so we use a ''
273
+ presented[presentable].new.send(:sanitize_for_mass_assignment, flat_attribute).empty?
274
+ end
275
+
314
276
  end
315
277
  end
@@ -1,9 +1,10 @@
1
1
  module ActivePresenter
2
2
  module VERSION
3
- MAJOR = 1
4
- MINOR = 4
3
+ MAJOR = 2
4
+ MINOR = 0
5
5
  TINY = 0
6
-
7
- STRING = [MAJOR, MINOR, TINY].join('.')
6
+ EXTRA = "a"
7
+
8
+ STRING = [MAJOR, MINOR, TINY].join('.') + EXTRA
8
9
  end
9
10
  end
data/lib/tasks/gem.rake CHANGED
@@ -1,4 +1,4 @@
1
- require 'rake/gempackagetask'
1
+ require 'rubygems/package_task'
2
2
 
3
3
  task :clean => :clobber_package
4
4
 
@@ -21,7 +21,7 @@ spec = Gem::Specification.new do |s|
21
21
  s.require_path = "lib"
22
22
  end
23
23
 
24
- Rake::GemPackageTask.new(spec) do |p|
24
+ Gem::PackageTask.new(spec) do |p|
25
25
  p.gem_spec = spec
26
26
  end
27
27
 
data/test/base_test.rb CHANGED
@@ -45,34 +45,34 @@ Expectations do
45
45
  expect SignupPresenter.new.not.to.be.valid?
46
46
  expect SignupPresenter.new(:user => User.new(hash_for_user)).to.be.valid?
47
47
 
48
- expect ActiveRecord::Errors do
48
+ expect ActiveModel::Errors do
49
49
  s = SignupPresenter.new
50
50
  s.valid?
51
51
  s.errors
52
52
  end
53
53
 
54
- expect ActiveRecord::Errors do
54
+ expect ActiveModel::Errors do
55
55
  s = SignupPresenter.new
56
56
  s.valid?
57
57
  s.user_errors
58
58
  end
59
59
 
60
- expect ActiveRecord::Errors do
60
+ expect ActiveModel::Errors do
61
61
  s = SignupPresenter.new
62
62
  s.valid?
63
63
  s.account_errors
64
64
  end
65
65
 
66
- expect String do
66
+ expect ["can't be blank"] do
67
67
  s = SignupPresenter.new
68
68
  s.valid?
69
- s.errors.on(:user_login)
69
+ s.errors[:user_login]
70
70
  end
71
71
 
72
- expect "can't be blank" do
72
+ expect ["can't be blank"] do
73
73
  s = SignupPresenter.new
74
74
  s.valid?
75
- s.errors.on(:user_login)
75
+ s.errors[:user_login]
76
76
  end
77
77
 
78
78
  expect ["User Password can't be blank"] do
@@ -81,13 +81,13 @@ Expectations do
81
81
  s.errors.full_messages
82
82
  end
83
83
 
84
- expect 'c4N n07 83 8L4nK' do
84
+ expect ['c4N n07 83 8L4nK'] do
85
85
  old_locale = I18n.locale
86
86
  I18n.locale = '1337'
87
87
 
88
88
  s = SignupPresenter.new(:user_login => nil)
89
89
  s.valid?
90
- message = s.errors.on(:user_login)
90
+ message = s.errors[:user_login]
91
91
 
92
92
  I18n.locale = old_locale
93
93
 
@@ -143,7 +143,7 @@ Expectations do
143
143
  end
144
144
 
145
145
  expect Account.any_instance.to.receive(:save!) do
146
- User.any_instance.stubs(:save!)
146
+ User.any_instance.stubs(:save!).returns(true)
147
147
  s = SignupPresenter.new(:user_login => "da", :user_password => "seekrit")
148
148
  s.save!
149
149
  end
@@ -173,7 +173,7 @@ Expectations do
173
173
  s.update_attributes :user_login => 'Something Different'
174
174
  s.user_login
175
175
  end
176
-
176
+
177
177
  # Multiparameter assignment
178
178
  expect Time.parse('March 27 1980 9:30:59 am') do
179
179
  s = SignupPresenter.new
@@ -192,23 +192,23 @@ Expectations do
192
192
  s = SignupPresenter.new
193
193
  s.attributes = nil
194
194
  end
195
-
195
+
196
196
  # this is a regression test to make sure that _title is working. we had a weird conflict with using String#delete
197
197
  expect 'something' do
198
198
  s = SignupPresenter.new :account_title => 'something'
199
199
  s.account_title
200
200
  end
201
201
 
202
- expect String do
202
+ expect ["can't be blank"] do
203
203
  s = SignupPresenter.new
204
204
  s.save
205
- s.errors.on(:user_login)
205
+ s.errors[:user_login]
206
206
  end
207
207
 
208
- expect String do
208
+ expect ["can't be blank"] do
209
209
  s = SignupPresenter.new
210
210
  s.save! rescue
211
- s.errors.on(:user_login)
211
+ s.errors[:user_login]
212
212
  end
213
213
 
214
214
  expect 'Login' do
@@ -219,7 +219,7 @@ Expectations do
219
219
  expect SignupPresenter do
220
220
  SignupPresenter.new(nil)
221
221
  end
222
-
222
+
223
223
  expect EndingWithSPresenter.new.address.not.to.be.nil?
224
224
 
225
225
  # this should act as ActiveRecord models do
@@ -237,25 +237,25 @@ Expectations do
237
237
  presenter.save!
238
238
  end.id
239
239
  end
240
-
240
+
241
241
  expect CantSavePresenter.new.not.to.be.save # it won't save because the filter chain will halt
242
-
242
+
243
243
  expect ActiveRecord::RecordNotSaved do
244
244
  CantSavePresenter.new.save!
245
245
  end
246
-
246
+
247
247
  expect 'Some Street' do
248
248
  p = AfterSavePresenter.new
249
249
  p.save
250
250
  p.address.street
251
251
  end
252
-
252
+
253
253
  expect 'Some Street' do
254
254
  p = AfterSavePresenter.new
255
255
  p.save!
256
256
  p.address.street
257
257
  end
258
-
258
+
259
259
  expect SamePrefixPresenter.new.to.be.respond_to?(:account_title)
260
260
  expect SamePrefixPresenter.new.to.be.respond_to?(:account_info_info)
261
261
 
@@ -305,7 +305,7 @@ Expectations do
305
305
  end.steps
306
306
  end
307
307
 
308
- expect ActiveRecord::Errors.any_instance.to.receive(:clear).twice do
308
+ expect ActiveModel::Errors.any_instance.to.receive(:clear) do
309
309
  CallbackCantValidatePresenter.new.valid?
310
310
  end
311
311
 
@@ -329,34 +329,33 @@ Expectations do
329
329
  expect Address do
330
330
  PresenterWithTwoAddresses.new.secondary_address
331
331
  end
332
-
332
+
333
333
  expect "123 awesome st" do
334
334
  p = PresenterWithTwoAddresses.new(:secondary_address_street => "123 awesome st")
335
335
  p.save
336
336
  p.secondary_address_street
337
337
  end
338
-
338
+
339
339
  # attr_protected
340
340
  expect "" do
341
341
  p = SignupPresenter.new(:account_secret => 'swordfish')
342
342
  p.account.secret
343
343
  end
344
-
344
+
345
345
  expect "comment" do
346
346
  p = HistoricalPresenter.new(:history_comment => 'comment', :user => User.new(hash_for_user))
347
347
  p.save
348
348
  p.history_comment
349
349
  end
350
-
350
+
351
351
  expect false do
352
352
  SignupPresenter.new.changed?
353
353
  end
354
-
354
+
355
355
  expect true do
356
356
  p = SignupPresenter.new(:user => User.new(hash_for_user))
357
357
  p.save
358
358
  p.user_login = 'something_else'
359
359
  p.changed?
360
360
  end
361
-
362
361
  end
data/test/lint_test.rb ADDED
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__)+'/test_helper'
2
+ require 'test/unit'
3
+
4
+ class LintTest < ActiveModel::TestCase
5
+ include ActiveModel::Lint::Tests
6
+
7
+ def setup
8
+ @model = SignupPresenter.new
9
+ end
10
+ end
data/test/test_helper.rb CHANGED
@@ -1,4 +1,3 @@
1
- require File.dirname(__FILE__)+'/../lib/active_presenter' unless defined?(ActivePresenter)
2
1
  require 'expectations'
3
2
  require 'logger'
4
3
 
@@ -51,7 +50,6 @@ ActiveRecord::Schema.define(:version => 0) do
51
50
  t.string :action, :default => ''
52
51
  t.datetime :created_at
53
52
  end
54
-
55
53
  end
56
54
 
57
55
  class User < ActiveRecord::Base
@@ -64,12 +62,12 @@ class User < ActiveRecord::Base
64
62
  if password.blank?
65
63
  attribute_name = I18n.t(:password, {:default => "Password", :scope => [:activerecord, :attributes, :user]})
66
64
  error_message = I18n.t(:blank, {:default => "can't be blank", :scope => [:activerecord, :errors, :messages]})
67
- errors.add_to_base("#{attribute_name} #{error_message}")
65
+ errors[:base] << ("#{attribute_name} #{error_message}")
68
66
  end
69
67
  end
70
68
  end
71
- class Account < ActiveRecord::Base; end
72
- class History < ActiveRecord::Base; end
69
+ class Account < ActiveRecord::Base ;end
70
+ class History < ActiveRecord::Base ;end
73
71
  class Address < ActiveRecord::Base; end
74
72
  class AccountInfo < ActiveRecord::Base; end
75
73
 
@@ -86,11 +84,6 @@ class EndingWithSPresenter < ActivePresenter::Base
86
84
  presents :address
87
85
  end
88
86
 
89
- class HistoricalPresenter < ActivePresenter::Base
90
- presents :user, :history
91
- attr_accessible :history_comment
92
- end
93
-
94
87
  class CantSavePresenter < ActivePresenter::Base
95
88
  presents :address
96
89
 
@@ -103,7 +96,7 @@ class SignupNoAccountPresenter < ActivePresenter::Base
103
96
  presents :account, :user
104
97
 
105
98
  def save?(key, instance)
106
- key != :account
99
+ key.to_sym != :account
107
100
  end
108
101
  end
109
102
 
@@ -212,7 +205,16 @@ class CallbackCantValidatePresenter < ActivePresenter::Base
212
205
  end
213
206
  end
214
207
 
208
+ class HistoricalPresenter < ActivePresenter::Base
209
+ presents :user, :history
210
+ attr_accessible :history_comment
211
+ end
212
+
215
213
  def hash_for_user(opts = {})
216
214
  {:login => 'jane', :password => 'seekrit' }.merge(opts)
217
215
  end
218
216
 
217
+ def returning(value)
218
+ yield(value)
219
+ value
220
+ end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_presenter
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease:
4
+ hash: 10
5
+ prerelease: 5
6
6
  segments:
7
- - 1
8
- - 4
7
+ - 2
9
8
  - 0
10
- version: 1.4.0
9
+ - 0
10
+ - a
11
+ version: 2.0.0a
11
12
  platform: ruby
12
13
  authors:
13
14
  - James Golick & Daniel Haran
@@ -15,7 +16,8 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-09-23 00:00:00 Z
19
+ date: 2011-09-26 00:00:00 -07:00
20
+ default_executable:
19
21
  dependencies: []
20
22
 
21
23
  description: ActivePresenter is the presenter library you already know! (...if you know ActiveRecord)
@@ -36,7 +38,9 @@ files:
36
38
  - lib/tasks/doc.rake
37
39
  - lib/tasks/gem.rake
38
40
  - test/base_test.rb
41
+ - test/lint_test.rb
39
42
  - test/test_helper.rb
43
+ has_rdoc: true
40
44
  homepage: http://jamesgolick.com/active_presenter
41
45
  licenses: []
42
46
 
@@ -59,16 +63,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
59
63
  required_rubygems_version: !ruby/object:Gem::Requirement
60
64
  none: false
61
65
  requirements:
62
- - - ">="
66
+ - - ">"
63
67
  - !ruby/object:Gem::Version
64
- hash: 3
68
+ hash: 25
65
69
  segments:
66
- - 0
67
- version: "0"
70
+ - 1
71
+ - 3
72
+ - 1
73
+ version: 1.3.1
68
74
  requirements: []
69
75
 
70
76
  rubyforge_project: active_presenter
71
- rubygems_version: 1.8.10
77
+ rubygems_version: 1.3.9.3
72
78
  signing_key:
73
79
  specification_version: 3
74
80
  summary: ActivePresenter is the presenter library you already know! (...if you know ActiveRecord)