exposure 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.7
1
+ 0.1.0
@@ -12,24 +12,62 @@ module Exposure
12
12
  end
13
13
 
14
14
  def build_default_builder(member, nesting)
15
- self::const_set(:DefaultBuilder, {
16
- self.resource_name.intern => Proc.new { [:new, params[resource_name] ] }
17
- })
15
+ if nesting.any?
16
+ builders = self::const_set(:DefaultBuilders, {
17
+ self.resource_name.intern => Proc.new { [:build, params[resource_name] ] },
18
+ })
19
+ else
20
+ self::const_set(:DefaultBuilders, {
21
+ self.resource_name.intern => Proc.new { [:new, params[resource_name] ] },
22
+ })
23
+ end
18
24
  end
19
25
  end
20
26
 
21
27
  module InstaneMethods
22
28
  private
23
29
  def custom_builder_for(resource_name)
24
-
30
+ if builder = self.class::Builders[resource_name]
31
+ return builder
32
+ end
25
33
  end
26
34
 
27
35
  def default_builder_for(resource_name)
28
-
36
+ if builder = self.class::DefaultBuilders[resource_name]
37
+ return builder
38
+ end
29
39
  end
30
40
 
31
41
  def builder_for(resource_name)
32
- custom_builder_for(resource_name) || default_builder_for(resource_name)
42
+ custom_builder_for(resource_name) || default_builder_for(resource_name) || finder_for(resource_name)
43
+ end
44
+
45
+ def call_builder_chain(object, chain, use_associaiton = true)
46
+ chain = chain.clone
47
+ links = chain.shift
48
+ return object unless links
49
+
50
+ message = builder_for(links[0])
51
+ association = links[1] if use_associaiton
52
+
53
+ case message
54
+ when Symbol
55
+ value = self.send(message)
56
+ when Proc
57
+ value = self.instance_eval(&message)
58
+ else
59
+ raise "invalid builder of #{message.inspect}"
60
+ end
61
+
62
+ if value.kind_of?(Array) && !value.respond_to?(:proxy_target)
63
+ if use_associaiton
64
+ call_builder_chain(object.send(association).send(*value), chain)
65
+ else
66
+ call_builder_chain(object.send(*value), chain)
67
+ end
68
+ else
69
+ call_builder_chain(value, chain)
70
+ end
33
71
  end
34
72
  end
35
73
  end
@@ -13,7 +13,7 @@ module Exposure
13
13
  build_callback('before', trigger, action, options)
14
14
  end
15
15
  end
16
-
16
+
17
17
  # access point for creating and configuring after_ callbacks.
18
18
  def after(trigger, *actions)
19
19
  options = actions.extract_options!
@@ -25,24 +25,24 @@ module Exposure
25
25
  # builds callbacks that adhere to the ActiveSupport::Callbacks interface
26
26
  def build_callback(prefix, trigger, action, options) #:nodoc:
27
27
  callback_name = "#{prefix}_#{trigger}"
28
-
28
+
29
29
  if options[:on]
30
30
  callback_name += "_on_#{options.delete(:on)}"
31
31
  end
32
-
32
+
33
33
  options[:if] ||= []
34
-
34
+
35
35
  only_methods = options.delete(:only)
36
36
  except_methods = options.delete(:except)
37
-
37
+
38
38
  if only_methods
39
39
  options[:if] << Proc.new {|c| only_methods.include?(c.action_name.intern) }
40
40
  end
41
-
41
+
42
42
  if except_methods
43
43
  options[:if] << Proc.new {|c| !except_methods.include?(c.action_name.intern) }
44
44
  end
45
-
45
+
46
46
  self.send(callback_name, action, options)
47
47
  end
48
48
  end
@@ -54,12 +54,13 @@ module Exposure
54
54
  end
55
55
 
56
56
  def call_finder_chain(object, chain, use_associaiton = true)
57
+ chain = chain.clone
57
58
  links = chain.shift
58
59
  return object unless links
59
-
60
+
60
61
  message = finder_for(links[0])
61
62
  association = links[1] if use_associaiton
62
-
63
+
63
64
  case message
64
65
  when Symbol
65
66
  value = self.send(message)
@@ -68,7 +69,7 @@ module Exposure
68
69
  else
69
70
  raise "invalid finder of #{message.inspect}"
70
71
  end
71
-
72
+
72
73
  if value.kind_of?(Array) && !value.respond_to?(:proxy_target)
73
74
  if use_associaiton
74
75
  call_finder_chain(object.send(association).send(*value), chain)
@@ -17,7 +17,7 @@ module Exposure
17
17
  # can be a Proc or method name as symbol.
18
18
  def flash_for(action_name, options = {}, &block)
19
19
  options[:is] ||= block
20
-
20
+
21
21
  case options[:on]
22
22
  when NilClass, :any
23
23
  self.const_get(:FlashMessages)["#{action_name}.success.html"] = options[:is]
@@ -46,13 +46,13 @@ module Exposure
46
46
  false
47
47
  end
48
48
  end
49
-
49
+
50
50
  def default_flash_for(action_name, action_status)
51
51
  if message_proc = self.class::DefaultFlashMessages["#{action_name}.#{action_status}.html"]
52
52
  flash[:message] = self.instance_eval(&message_proc)
53
53
  end
54
54
  end
55
-
55
+
56
56
  def flash_for(action_name, action_successful)
57
57
  custom_flash_for(action_name, action_successful) || default_flash_for(action_name, action_successful)
58
58
  end
@@ -27,7 +27,7 @@ module Exposure
27
27
  options = actions.extract_options!
28
28
  options[:is] ||= block
29
29
  formats = options[:formats] || [:html]
30
-
30
+
31
31
  case options[:on]
32
32
  when NilClass, :any
33
33
  build_custom_response(actions, :success, formats, options[:is])
@@ -62,7 +62,7 @@ module Exposure
62
62
  false
63
63
  end
64
64
  end
65
-
65
+
66
66
  def default_response_for(action_name, action_status, format)
67
67
  if responder = self.class::DefaultResponses["#{action_name}.#{action_status}.#{format}"]
68
68
  self.instance_eval &responder
@@ -70,7 +70,7 @@ module Exposure
70
70
  return false
71
71
  end
72
72
  end
73
-
73
+
74
74
  def response_for(action_name, action_status, format = :html)
75
75
  format = :html if format == :all
76
76
  custom_response_for(action_name, action_status, format) || default_response_for(action_name, action_status, format) || head(:not_acceptable)
@@ -25,6 +25,7 @@ module Exposure
25
25
 
26
26
  include ActiveSupport::Callbacks
27
27
  include Exposure::Finding
28
+ include Exposure::Building
28
29
  include Exposure::Flashing
29
30
  include Exposure::Responding
30
31
  include Exposure::Callbacks
@@ -1,52 +1,54 @@
1
1
  module Exposure
2
2
  module Configuration
3
3
  module Options
4
-
5
4
  def allow_actions!
6
5
  if @_exposed_resource_options[:only]
7
6
  @_exposed_resource_options[:except] = Patterns::Resources::DefaultActions - @_exposed_resource_options[:only]
8
7
  end
9
-
8
+
10
9
  if @_exposed_resource_options[:except]
11
10
  @_exposed_resource_options[:except].each do |action|
12
11
  undef_method(action)
13
12
  end
14
13
  end
15
14
  end
16
-
15
+
17
16
  def allow_formats!
18
17
  formats = @_exposed_resource_options[:formats] || [:html, :xml]
19
18
  end
20
-
19
+
21
20
  def name!
22
21
  self.resource_name = @_exposed_resource_name.to_s.singularize
23
22
  self.resources_name = @_exposed_resource_name.to_s
24
23
  end
25
-
24
+
26
25
  def build_default_finders!
27
26
  if nesting = @_exposed_resource_options[:nested]
28
27
  self.build_nested_default_finders!(nesting)
29
28
  return
30
29
  end
31
-
30
+
32
31
  self.parent_model = self.resource_name.camelize.constantize
33
32
  build_default_finders(self.resource_name, [])
34
33
  self.member_nesting = [ [self.resource_name.to_sym] ]
35
34
  self.collection_nesting = [ [self.resources_name.to_sym] ]
36
35
  end
37
-
36
+
38
37
  def build_default_builders!
39
- true
38
+ nesting = @_exposed_resource_options[:nested] || []
39
+ nesting = nesting.clone
40
+ nesting.shift
41
+ build_default_builder(self.resources_name, nesting)
40
42
  end
41
-
43
+
42
44
  def build_nested_default_finders!(nesting)
43
-
45
+ nesting = nesting.clone
44
46
  self.parent_model = nesting.shift.to_s.singularize.camelize.constantize
45
-
47
+
46
48
  build_default_finders(self.resources_name, nesting)
47
-
48
- nesting.collect! {|sym| [sym.to_s.singularize.to_sym, sym]}
49
-
49
+
50
+ nesting = nesting.collect! {|sym| [sym.to_s.singularize.to_sym, sym]}
51
+
50
52
  self.member_nesting = nesting + [ [self.resource_name.to_sym] ]
51
53
  self.collection_nesting = nesting + [ [self.resources_name.to_sym] ]
52
54
  end
@@ -5,6 +5,7 @@ module Exposure
5
5
  base::const_set(:DefaultResponses, DefaultResponses)
6
6
  base::const_set(:DefaultFlashMessages, DefaultFlashMessages)
7
7
  base::const_set(:Finders, { true => {}, false => {} })
8
+ base::const_set(:Builders, {})
8
9
  base::const_set(:FlashMessages, {})
9
10
  base::const_set(:Responses, {} )
10
11
  end
@@ -208,15 +209,15 @@ module Exposure
208
209
  end
209
210
 
210
211
  def build_record
211
- @resource = instance_variable_set("@#{resource_name}", parent_model.new(params[resource_name]))
212
+ @resource = instance_variable_set("@#{resource_name}", call_builder_chain(parent_model, self.class.member_nesting, false))
212
213
  end
213
214
 
214
215
  def find_record
215
- @resource = instance_variable_set("@#{resource_name}", call_finder_chain(parent_model, self.class.member_nesting.clone, false))
216
+ @resource = instance_variable_set("@#{resource_name}", call_finder_chain(parent_model, self.class.member_nesting, false))
216
217
  end
217
218
 
218
219
  def find_records
219
- @resources = instance_variable_set("@#{resources_name}", call_finder_chain(parent_model, self.class.collection_nesting.clone, false))
220
+ @resources = instance_variable_set("@#{resources_name}", call_finder_chain(parent_model, self.class.collection_nesting, false))
220
221
  end
221
222
 
222
223
  def delete_record
data/lib/exposure.rb CHANGED
@@ -12,7 +12,7 @@ require 'exposure/behaviors/responding'
12
12
  require 'exposure/patterns/resources'
13
13
 
14
14
  module Exposure
15
- VERSION = '0.0.6'
15
+ VERSION = File.read(File.join(File.dirname(__FILE__), '../VERSION')).strip!.freeze
16
16
  def self.included(base)
17
17
  base.extend Configuration
18
18
  end
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "builders", :type => :controller do
4
+ setup = lambda {
5
+ class PiratesController < ActionController::Base
6
+ expose_many(:pirates)
7
+ private
8
+ def build_pirate
9
+ Pirate.new(params[:pirate])
10
+ end
11
+ end
12
+
13
+ ActionController::Routing::Routes.draw do |map|
14
+ map.resources :pirates
15
+ end
16
+ }
17
+
18
+ setup.call
19
+ controller_name :pirates
20
+ Object.remove_class(PiratesController)
21
+
22
+ before(:each) do
23
+ setup.call
24
+ @controller = PiratesController.new
25
+ @request = ActionController::TestRequest.new
26
+ @response = ActionController::TestResponse.new
27
+
28
+ @pirate = Factory.stub(:pirate)
29
+ Pirate.stub(:new => @pirate)
30
+ end
31
+
32
+ after(:each) do
33
+ Object.remove_class(PiratesController)
34
+ end
35
+
36
+ it "builds with a proc" do
37
+ PiratesController.build :pirate, :with => Proc.new { Pirate.new(params[:pirate]) }
38
+ post(:create, {:pirate => {}}).inspect
39
+
40
+ should assign_to(:pirate).with(@pirate)
41
+ end
42
+
43
+ it "finds with a method name as symbol" do
44
+ PiratesController.build :pirate, :with => :build_pirate
45
+ post(:create, {:pirate => {}})
46
+
47
+ should assign_to(:pirate).with(@pirate)
48
+ end
49
+
50
+ it "finds with a block" do
51
+ PiratesController.build :pirate do
52
+ Pirate.new(params[:pirate])
53
+ end
54
+
55
+ post(:create, {:pirate => {}})
56
+
57
+ should assign_to(:pirate).with(@pirate)
58
+ end
59
+ end
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "nested builders", :type => :controller do
4
+ setup = lambda {
5
+ class ShipsController < ActionController::Base
6
+ expose_many(:ships, :nested => [:pirates])
7
+ end
8
+
9
+ ActionController::Routing::Routes.draw do |map|
10
+ map.resources :pirates do |pirate|
11
+ pirate.resources :ships
12
+ end
13
+ end
14
+ }
15
+
16
+ setup.call
17
+ controller_name :ships
18
+ Object.remove_class(ShipsController)
19
+
20
+ before(:each) do
21
+ setup.call
22
+ @controller = ShipsController.new
23
+ @request = ActionController::TestRequest.new
24
+ @response = ActionController::TestResponse.new
25
+
26
+ @pirate = Factory.create(:pirate_with_ships)
27
+ Pirate.stub(:find => @pirate)
28
+
29
+ get(:new, {:pirate_id => 1, :ship => nil})
30
+ end
31
+
32
+ after(:each) do
33
+ Object.remove_class(ShipsController)
34
+ end
35
+
36
+ it { should assign_to(:ship) }
37
+ it { should assign_to(:resource) }
38
+
39
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exposure
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Trek Glowacki
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-26 00:00:00 -04:00
12
+ date: 2009-11-10 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -39,6 +39,8 @@ files:
39
39
  - script/console
40
40
  - script/destroy
41
41
  - script/generate
42
+ - spec/builders/builder_spec.rb
43
+ - spec/builders/nested_builder_spec.rb
42
44
  - spec/callbacks_spec.rb
43
45
  - spec/configuration_spec.rb
44
46
  - spec/custom_matchers.rb
@@ -99,6 +101,8 @@ signing_key:
99
101
  specification_version: 3
100
102
  summary: exposed resources
101
103
  test_files:
104
+ - spec/builders/builder_spec.rb
105
+ - spec/builders/nested_builder_spec.rb
102
106
  - spec/callbacks_spec.rb
103
107
  - spec/configuration_spec.rb
104
108
  - spec/custom_matchers.rb