active_presenter 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- require 'activerecord'
2
+ require 'active_record'
3
3
  Dir.glob(File.dirname(__FILE__)+'/active_presenter/**/*.rb').each { |l| require l }
4
4
 
5
5
  module ActivePresenter
@@ -6,6 +6,7 @@ module ActivePresenter
6
6
  define_callbacks :before_validation, :before_save, :after_save
7
7
 
8
8
  class_inheritable_accessor :presented
9
+ class_inheritable_accessor :attr_protected, :attr_accessible
9
10
  self.presented = {}
10
11
 
11
12
  # Indicates which models are to be presented by this presenter.
@@ -67,6 +68,30 @@ module ActivePresenter
67
68
  I18n.translate(defaults.shift, {:scope => [:activerecord, :models], :count => 1, :default => defaults}.merge(options))
68
69
  end
69
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
+
70
95
  # 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:
71
96
  #
72
97
  # 1. SignupPresenter.new(:user_login => 'james', :user_password => 'swordfish', :user_password_confirmation => 'swordfish', :account_subdomain => 'giraffesoft')
@@ -96,8 +121,10 @@ module ActivePresenter
96
121
  #
97
122
  def attributes=(attrs)
98
123
  return if attrs.nil?
99
-
124
+
125
+ attrs = attrs.stringify_keys
100
126
  multi_parameter_attributes = {}
127
+ attrs = remove_attributes_protected_from_mass_assignment(attrs)
101
128
 
102
129
  attrs.each do |k,v|
103
130
  if (base_attribute = k.to_s.split("(").first) != k.to_s
@@ -148,6 +175,11 @@ module ActivePresenter
148
175
  end
149
176
  end
150
177
 
178
+ # Do any of the attributes have unsaved changes?
179
+ def changed?
180
+ presented_instances.map(&:changed?).any?
181
+ end
182
+
151
183
  # Save all of the presentables, wrapped in a transaction.
152
184
  #
153
185
  # Returns true or false based on success.
@@ -212,7 +244,7 @@ module ActivePresenter
212
244
  def id # :nodoc:
213
245
  nil
214
246
  end
215
-
247
+
216
248
  def new_record?
217
249
  true
218
250
  end
@@ -266,5 +298,18 @@ module ActivePresenter
266
298
  def run_callbacks_with_halt(callback)
267
299
  run_callbacks(callback) { |result, object| result == false }
268
300
  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(/\(.+/,""))}
309
+ else
310
+ raise "Declare either attr_protected or attr_accessible for #{self.class}, but not both."
311
+ end
312
+ end
313
+
269
314
  end
270
315
  end
@@ -1,8 +1,8 @@
1
1
  module ActivePresenter
2
2
  module VERSION
3
3
  MAJOR = 1
4
- MINOR = 2
5
- TINY = 1
4
+ MINOR = 3
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -305,7 +305,7 @@ Expectations do
305
305
  end.steps
306
306
  end
307
307
 
308
- expect ActiveRecord::Errors.any_instance.to.receive(:clear) do
308
+ expect ActiveRecord::Errors.any_instance.to.receive(:clear).twice do
309
309
  CallbackCantValidatePresenter.new.valid?
310
310
  end
311
311
 
@@ -335,4 +335,28 @@ Expectations do
335
335
  p.save
336
336
  p.secondary_address_street
337
337
  end
338
+
339
+ # attr_protected
340
+ expect "" do
341
+ p = SignupPresenter.new(:account_secret => 'swordfish')
342
+ p.account.secret
343
+ end
344
+
345
+ expect "comment" do
346
+ p = HistoricalPresenter.new(:history_comment => 'comment', :user => User.new(hash_for_user))
347
+ p.save
348
+ p.history_comment
349
+ end
350
+
351
+ expect false do
352
+ SignupPresenter.new.changed?
353
+ end
354
+
355
+ expect true do
356
+ p = SignupPresenter.new(:user => User.new(hash_for_user))
357
+ p.save
358
+ p.user_login = 'something_else'
359
+ p.changed?
360
+ end
361
+
338
362
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__)+'/../lib/active_presenter'
1
+ require File.dirname(__FILE__)+'/../lib/active_presenter' unless defined?(ActivePresenter)
2
2
  require 'expectations'
3
3
  require 'logger'
4
4
 
@@ -34,6 +34,7 @@ ActiveRecord::Schema.define(:version => 0) do
34
34
  create_table :accounts do |t|
35
35
  t.string :subdomain, :default => ''
36
36
  t.string :title, :default => ''
37
+ t.string :secret, :default => ''
37
38
  end
38
39
 
39
40
  create_table :addresses do |t|
@@ -43,6 +44,14 @@ ActiveRecord::Schema.define(:version => 0) do
43
44
  create_table :account_infos do |t|
44
45
  t.string :info
45
46
  end
47
+
48
+ create_table :histories do |t|
49
+ t.integer :user_id
50
+ t.string :comment, :default => ''
51
+ t.string :action, :default => ''
52
+ t.datetime :created_at
53
+ end
54
+
46
55
  end
47
56
 
48
57
  class User < ActiveRecord::Base
@@ -60,6 +69,7 @@ class User < ActiveRecord::Base
60
69
  end
61
70
  end
62
71
  class Account < ActiveRecord::Base; end
72
+ class History < ActiveRecord::Base; end
63
73
  class Address < ActiveRecord::Base; end
64
74
  class AccountInfo < ActiveRecord::Base; end
65
75
 
@@ -69,12 +79,18 @@ end
69
79
 
70
80
  class SignupPresenter < ActivePresenter::Base
71
81
  presents :account, :user
82
+ attr_protected :account_secret
72
83
  end
73
84
 
74
85
  class EndingWithSPresenter < ActivePresenter::Base
75
86
  presents :address
76
87
  end
77
88
 
89
+ class HistoricalPresenter < ActivePresenter::Base
90
+ presents :user, :history
91
+ attr_accessible :history_comment
92
+ end
93
+
78
94
  class CantSavePresenter < ActivePresenter::Base
79
95
  presents :address
80
96
 
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_presenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 3
9
+ - 0
10
+ version: 1.3.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - James Golick & Daniel Haran
@@ -9,7 +15,7 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-12-17 00:00:00 -08:00
18
+ date: 2010-10-19 00:00:00 -07:00
13
19
  default_executable:
14
20
  dependencies: []
15
21
 
@@ -42,21 +48,29 @@ rdoc_options: []
42
48
  require_paths:
43
49
  - lib
44
50
  required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
45
52
  requirements:
46
53
  - - ">="
47
54
  - !ruby/object:Gem::Version
55
+ hash: 61
56
+ segments:
57
+ - 1
58
+ - 8
59
+ - 5
48
60
  version: 1.8.5
49
- version:
50
61
  required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
51
63
  requirements:
52
64
  - - ">="
53
65
  - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
54
69
  version: "0"
55
- version:
56
70
  requirements: []
57
71
 
58
72
  rubyforge_project: active_presenter
59
- rubygems_version: 1.3.5
73
+ rubygems_version: 1.3.7
60
74
  signing_key:
61
75
  specification_version: 3
62
76
  summary: ActivePresenter is the presenter library you already know! (...if you know ActiveRecord)