fabrication 2.21.0 → 3.0.0.beta.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +1 -4
  3. data/Rakefile +8 -10
  4. data/lib/fabricate.rb +10 -13
  5. data/lib/fabrication.rb +4 -9
  6. data/lib/fabrication/config.rb +23 -22
  7. data/lib/fabrication/cucumber/step_fabricator.rb +20 -13
  8. data/lib/fabrication/errors/duplicate_fabricator_error.rb +5 -3
  9. data/lib/fabrication/errors/infinite_recursion_error.rb +5 -3
  10. data/lib/fabrication/errors/misplaced_fabricate_error.rb +7 -3
  11. data/lib/fabrication/errors/unfabricatable_error.rb +5 -4
  12. data/lib/fabrication/errors/unknown_fabricator_error.rb +5 -5
  13. data/lib/fabrication/generator/active_record.rb +18 -15
  14. data/lib/fabrication/generator/base.rb +93 -81
  15. data/lib/fabrication/generator/sequel.rb +29 -27
  16. data/lib/fabrication/railtie.rb +1 -3
  17. data/lib/fabrication/schematic/attribute.rb +69 -62
  18. data/lib/fabrication/schematic/definition.rb +139 -134
  19. data/lib/fabrication/schematic/evaluator.rb +61 -54
  20. data/lib/fabrication/schematic/manager.rb +67 -59
  21. data/lib/fabrication/schematic/runner.rb +12 -9
  22. data/lib/fabrication/sequencer.rb +23 -22
  23. data/lib/fabrication/support.rb +57 -54
  24. data/lib/fabrication/syntax/make.rb +0 -1
  25. data/lib/fabrication/transform.rb +34 -36
  26. data/lib/fabrication/version.rb +1 -1
  27. data/lib/rails/generators/fabrication/cucumber_steps/cucumber_steps_generator.rb +2 -3
  28. data/lib/rails/generators/fabrication/cucumber_steps/templates/fabrication_steps.rb +10 -10
  29. data/lib/rails/generators/fabrication/model/model_generator.rb +9 -9
  30. data/lib/tasks/defined_fabricators.rake +11 -11
  31. metadata +10 -12
  32. data/lib/fabrication/generator/data_mapper.rb +0 -17
  33. data/lib/fabrication/generator/mongoid.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a0d6dabff5b3d58e4abf5704c0c05084edc8733655015c0e43f941b08d64f73
4
- data.tar.gz: 5beb461b6679fbd5d4a73f29038dfdb85fccf22e7cb738e229771178b3020403
3
+ metadata.gz: 3153c373659350c2969d98f3d21cbc60c92f9aff1f00c51f32c7238357c49195
4
+ data.tar.gz: d69204cacb17bfab516ecbe93d2e05edb60c596052130a1b41340e699dc25412
5
5
  SHA512:
6
- metadata.gz: a04671cb31da952388f8df09576c7fcfcfd810b0441e6ef204c2f442d10de3e7c2831bee095a3dad10e439fb887d6d8fbd0c9c630632c3bc10b07f2f588d0ba8
7
- data.tar.gz: feb4242360e6236ec8c000257127365c2d095acbc0ad6d3c06a1f195e2d1bb8c0c57f43911da7fd4dbf910f4e6182b6b0d30dd1066abe32c5bbfabbcbfaab1bc
6
+ metadata.gz: 99e08637411f94b9df1ff63572c85b9b5fc8016677d043f53b1fb2acf27495b8f1cd1162b63cc6ed6be7579facf5e6dcc9c0929d2374fb6e7b30570308e33184
7
+ data.tar.gz: abffe3aeb00cb0b29589ad12daa9710801bdaecf5898d46b40e7cefa5150a0d00464df300c9edc54e22092097cdd0c712af0af5ae6b9f11f0ccd9965ce9b7582
data/README.markdown CHANGED
@@ -6,10 +6,7 @@ Fabrication is an object generation framework for Ruby.
6
6
 
7
7
  ## Compatibility
8
8
 
9
- Fabrication is tested against Ruby 2.2 and above.
10
-
11
- [![Build Status](https://secure.travis-ci.org/paulelliott/fabrication.png)](http://travis-ci.org/paulelliott/fabrication)
12
- [![Code Climate](https://codeclimate.com/github/paulelliott/fabrication.png)](https://codeclimate.com/github/paulelliott/fabrication)
9
+ Fabrication is tested against all officially supported versions of Ruby.
13
10
 
14
11
  ## Documentation
15
12
 
data/Rakefile CHANGED
@@ -1,20 +1,18 @@
1
- require "rubygems"
2
- require "bundler/setup"
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
3
 
4
4
  Bundler.require
5
5
 
6
- require "rspec/core/rake_task"
6
+ require 'rspec/core/rake_task'
7
7
  RSpec::Core::RakeTask.new(:spec) do |spec|
8
- spec.pattern = "spec/**/*_spec.rb"
8
+ spec.pattern = 'spec/**/*_spec.rb'
9
9
  end
10
10
 
11
11
  desc 'All cucumber features with kitchen sink appraisal'
12
12
  task :cucumber do
13
- system('appraisal kitchen-sink cucumber -f progress')
13
+ system('appraisal kitchen-sink cucumber -f progress --publish-quiet')
14
14
  end
15
15
 
16
- if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
17
- task default: [:cucumber, :appraisal]
18
- else
19
- task default: :spec
20
- end
16
+ default_task = ENV['APPRAISAL_INITIALIZED'] ? :spec : %i[cucumber appraisal]
17
+
18
+ task default: default_task
data/lib/fabricate.rb CHANGED
@@ -1,51 +1,48 @@
1
1
  class Fabricate
2
- def self.times(count, name, overrides={}, &block)
2
+ def self.times(count, name, overrides = {}, &block)
3
3
  count.times.map { Fabricate(name, overrides, &block) }
4
4
  end
5
5
 
6
- def self.build_times(count, name, overrides={}, &block)
6
+ def self.build_times(count, name, overrides = {}, &block)
7
7
  count.times.map { Fabricate.build(name, overrides, &block) }
8
8
  end
9
9
 
10
- def self.attributes_for_times(count, name, overrides={}, &block)
10
+ def self.attributes_for_times(count, name, overrides = {}, &block)
11
11
  count.times.map { Fabricate.attributes_for(name, overrides, &block) }
12
12
  end
13
13
 
14
- def self.attributes_for(name, overrides={}, &block)
14
+ def self.attributes_for(name, overrides = {}, &block)
15
15
  fail_if_initializing(name)
16
16
  schematic(name).to_attributes(overrides, &block)
17
17
  end
18
18
 
19
- def self.to_params(name, overrides={}, &block)
19
+ def self.to_params(name, overrides = {}, &block)
20
20
  fail_if_initializing(name)
21
21
  schematic(name).to_params(overrides, &block)
22
22
  end
23
23
 
24
- def self.build(name, overrides={}, &block)
24
+ def self.build(name, overrides = {}, &block)
25
25
  fail_if_initializing(name)
26
26
  schematic(name).build(overrides, &block).tap do |object|
27
27
  Fabrication::Cucumber::Fabrications[name] = object if Fabrication::Config.register_with_steps?
28
28
  end
29
29
  end
30
30
 
31
- def self.create(name, overrides={}, &block)
31
+ def self.create(name, overrides = {}, &block)
32
32
  fail_if_initializing(name)
33
33
  schematic(name).fabricate(overrides, &block)
34
34
  end
35
35
 
36
- def self.sequence(name=Fabrication::Sequencer::DEFAULT, start=nil, &block)
36
+ def self.sequence(name = Fabrication::Sequencer::DEFAULT, start = nil, &block)
37
37
  Fabrication::Sequencer.sequence(name, start, &block)
38
38
  end
39
39
 
40
40
  def self.schematic(name)
41
41
  Fabrication.manager.load_definitions if Fabrication.manager.empty?
42
- Fabrication.manager[name] || raise(Fabrication::UnknownFabricatorError.new(name))
42
+ Fabrication.manager[name] || raise(Fabrication::UnknownFabricatorError, name)
43
43
  end
44
44
 
45
- private
46
-
47
45
  def self.fail_if_initializing(name)
48
- raise Fabrication::MisplacedFabricateError.new(name) if Fabrication.manager.initializing?
46
+ raise Fabrication::MisplacedFabricateError, name if Fabrication.manager.initializing?
49
47
  end
50
-
51
48
  end
data/lib/fabrication.rb CHANGED
@@ -32,8 +32,6 @@ module Fabrication
32
32
  module Generator
33
33
  autoload :ActiveRecord, 'fabrication/generator/active_record'
34
34
  autoload :ActiveRecord4, 'fabrication/generator/active_record_4'
35
- autoload :DataMapper, 'fabrication/generator/data_mapper'
36
- autoload :Mongoid, 'fabrication/generator/mongoid'
37
35
  autoload :Sequel, 'fabrication/generator/sequel'
38
36
  autoload :Base, 'fabrication/generator/base'
39
37
  end
@@ -50,22 +48,19 @@ module Fabrication
50
48
  def self.manager
51
49
  @manager ||= Fabrication::Schematic::Manager.instance
52
50
  end
53
-
54
- def self.schematics
55
- puts "DEPRECATION WARNING: Fabrication.schematics has been replaced by Fabrication.manager and will be removed in 3.0.0."
56
- manager
57
- end
58
51
  end
59
52
 
60
- def Fabricator(name, options={}, &block)
53
+ # rubocop:disable Naming/MethodName
54
+ def Fabricator(name, options = {}, &block)
61
55
  Fabrication.manager.register(name, options, &block)
62
56
  end
63
57
 
64
- def Fabricate(name, overrides={}, &block)
58
+ def Fabricate(name, overrides = {}, &block)
65
59
  Fabricate.create(name, overrides, &block).tap do |object|
66
60
  Fabrication::Cucumber::Fabrications[name] = object if Fabrication::Config.register_with_steps?
67
61
  end
68
62
  end
63
+ # rubocop:enable Naming/MethodName
69
64
 
70
65
  module FabricationMethods
71
66
  def fabrications
@@ -2,14 +2,16 @@ module Fabrication
2
2
  module Config
3
3
  extend self
4
4
 
5
- def configure; yield self end
5
+ def configure
6
+ yield self
7
+ end
6
8
 
7
9
  def reset_defaults
8
10
  @fabricator_path =
9
11
  @path_prefix =
10
- @sequence_start =
11
- @generators =
12
- nil
12
+ @sequence_start =
13
+ @generators =
14
+ nil
13
15
  end
14
16
 
15
17
  def fabricator_path
@@ -17,44 +19,43 @@ module Fabrication
17
19
  end
18
20
  alias fabricator_paths fabricator_path
19
21
 
20
- def fabricator_dir
21
- puts "DEPRECATION WARNING: Fabrication::Config.fabricator_dir has been replaced by Fabrication::Config.fabricator_path"
22
- fabricator_path
23
- end
24
-
25
22
  def fabricator_path=(folders)
26
- @fabricator_path = (Array.new << folders).flatten
23
+ @fabricator_path = ([] << folders).flatten
27
24
  end
28
25
 
29
- def fabricator_dir=(folders)
30
- puts "DEPRECATION WARNING: Fabrication::Config.fabricator_dir has been replaced by Fabrication::Config.fabricator_path"
31
- self.fabricator_path = folders
32
- end
26
+ attr_writer :sequence_start, :register_with_steps
33
27
 
34
- attr_writer :sequence_start
35
- def sequence_start; @sequence_start ||= 0 end
28
+ def sequence_start
29
+ @sequence_start ||= 0
30
+ end
36
31
 
37
32
  def path_prefix=(folders)
38
- @path_prefix = (Array.new << folders).flatten
33
+ @path_prefix = ([] << folders).flatten
39
34
  end
40
35
 
41
36
  def path_prefix
42
- @path_prefix ||= [defined?(Rails) ? Rails.root : "."]
37
+ @path_prefix ||= [defined?(Rails) ? Rails.root : '.']
43
38
  end
44
39
  alias path_prefixes path_prefix
45
40
 
46
- attr_writer :register_with_steps
47
41
  def register_with_steps?
48
42
  @register_with_steps ||= nil
49
43
  end
50
44
 
51
- def generators; @generators ||= [] end
45
+ def generators
46
+ @generators ||= []
47
+ end
52
48
 
53
49
  def generator_for(default_generators, klass)
54
50
  (generators + default_generators).detect { |gen| gen.supports?(klass) }
55
51
  end
56
52
 
57
- def recursion_limit; @recursion_limit ||= 20 end
58
- def recursion_limit=(limit); @recursion_limit = limit end
53
+ def recursion_limit
54
+ @recursion_limit ||= 20
55
+ end
56
+
57
+ def recursion_limit=(limit)
58
+ @recursion_limit = limit
59
+ end
59
60
  end
60
61
  end
@@ -3,24 +3,27 @@ module Fabrication
3
3
  class StepFabricator
4
4
  attr_reader :model
5
5
 
6
- def initialize(model_name, opts ={})
6
+ def initialize(model_name, opts = {})
7
7
  @model = dehumanize(model_name)
8
8
  @fabricator = Fabrication::Support.singularize(@model).to_sym
9
9
  @parent_name = opts.delete(:parent)
10
10
  end
11
11
 
12
- def from_table(table, extra={})
12
+ def from_table(table, extra = {})
13
13
  hashes = singular? ? [table.rows_hash] : table.hashes
14
- hashes.map do |hash|
14
+ transformed_hashes = hashes.map do |hash|
15
15
  transformed_hash = Fabrication::Transform.apply_to(@model, parameterize_hash(hash))
16
16
  make(transformed_hash.merge(extra))
17
- end.tap {|o| remember(o) }
17
+ end
18
+ remember(transformed_hashes)
19
+ transformed_hashes
18
20
  end
19
21
 
20
- def n(count, attrs={})
21
- count.times.map { make(attrs) }.tap {|o| remember(o) }
22
+ def n(count, attrs = {})
23
+ count.times.map { make(attrs) }.tap { |o| remember(o) }
22
24
  end
23
25
 
26
+ # rubocop:disable Naming/PredicateName
24
27
  def has_many(children)
25
28
  instance = Fabrications[@fabricator]
26
29
  children = dehumanize(children)
@@ -29,9 +32,11 @@ module Fabrication
29
32
  child.respond_to?(:save!) && child.save!
30
33
  end
31
34
  end
35
+ # rubocop:enable Naming/PredicateName
32
36
 
33
37
  def parent
34
38
  return unless @parent_name
39
+
35
40
  Fabrications[dehumanize(@parent_name)]
36
41
  end
37
42
 
@@ -54,19 +59,20 @@ module Fabrication
54
59
  end
55
60
 
56
61
  def dehumanize(string)
57
- string.gsub(/\W+/,'_').downcase
62
+ string.gsub(/\W+/, '_').downcase
58
63
  end
59
64
 
60
65
  def parameterize_hash(hash)
61
- hash.inject({}) {|h,(k,v)| h.update(dehumanize(k).to_sym => v)}
66
+ hash.inject({}) { |h, (k, v)| h.update(dehumanize(k).to_sym => v) }
62
67
  end
63
68
 
64
- def make(attrs={})
69
+ def make(attrs = {})
65
70
  Fabricate(@fabricator, attrs.merge(parentship))
66
71
  end
67
72
 
68
73
  def parentship
69
74
  return {} unless parent
75
+
70
76
  parent_class_name = parent.class.to_s.underscore
71
77
 
72
78
  parent_instance = parent
@@ -77,18 +83,19 @@ module Fabrication
77
83
 
78
84
  { parent_class_name => parent_instance }
79
85
  end
80
-
81
86
  end
82
87
 
83
88
  module Fabrications
84
- @@fabrications = {}
89
+ def self.fabrications
90
+ @fabrications ||= {}
91
+ end
85
92
 
86
93
  def self.[](fabricator)
87
- @@fabrications[fabricator.to_sym]
94
+ fabrications[fabricator.to_sym]
88
95
  end
89
96
 
90
97
  def self.[]=(fabricator, fabrication)
91
- @@fabrications[fabricator.to_sym] = fabrication
98
+ fabrications[fabricator.to_sym] = fabrication
92
99
  end
93
100
  end
94
101
  end
@@ -1,5 +1,7 @@
1
- class Fabrication::DuplicateFabricatorError < StandardError
2
- def initialize(string)
3
- super("'#{string}' is already defined")
1
+ module Fabrication
2
+ class DuplicateFabricatorError < StandardError
3
+ def initialize(string)
4
+ super("'#{string}' is already defined")
5
+ end
4
6
  end
5
7
  end
@@ -1,5 +1,7 @@
1
- class Fabrication::InfiniteRecursionError < StandardError
2
- def initialize(name)
3
- super("You appear to have infinite recursion with the `#{name}` fabricator")
1
+ module Fabrication
2
+ class InfiniteRecursionError < StandardError
3
+ def initialize(name)
4
+ super("You appear to have infinite recursion with the `#{name}` fabricator")
5
+ end
4
6
  end
5
7
  end
@@ -1,5 +1,9 @@
1
- class Fabrication::MisplacedFabricateError < StandardError
2
- def initialize(name)
3
- super("You tried to fabricate `#{name}` while Fabricators were still loading. Check your fabricator files and make sure you didn't accidentally type `Fabricate` instead of `Fabricator` in there somewhere.")
1
+ module Fabrication
2
+ class MisplacedFabricateError < StandardError
3
+ def initialize(name)
4
+ super("You tried to fabricate `#{name}` while Fabricators were still loading. " \
5
+ "Check your fabricator files and make sure you didn't accidentally type " \
6
+ '`Fabricate` instead of `Fabricator` in there somewhere.')
7
+ end
4
8
  end
5
9
  end
@@ -1,6 +1,7 @@
1
- class Fabrication::UnfabricatableError < StandardError
2
-
3
- def initialize(name, original_error)
4
- super("No class found for '#{name}' (original exception: #{original_error.message})")
1
+ module Fabrication
2
+ class UnfabricatableError < StandardError
3
+ def initialize(name, original_error)
4
+ super("No class found for '#{name}' (original exception: #{original_error.message})")
5
+ end
5
6
  end
6
7
  end
@@ -1,7 +1,7 @@
1
- class Fabrication::UnknownFabricatorError < StandardError
2
-
3
- def initialize(name)
4
- super("No Fabricator defined for '#{name}'")
1
+ module Fabrication
2
+ class UnknownFabricatorError < StandardError
3
+ def initialize(name)
4
+ super("No Fabricator defined for '#{name}'")
5
+ end
5
6
  end
6
-
7
7
  end
@@ -1,19 +1,22 @@
1
- class Fabrication::Generator::ActiveRecord < Fabrication::Generator::Base
1
+ module Fabrication
2
+ module Generator
3
+ class ActiveRecord < Fabrication::Generator::Base
4
+ def self.supports?(klass)
5
+ # Some gems will declare an ActiveRecord module for their own purposes
6
+ # so we can't assume because we have the ActiveRecord module that we also
7
+ # have ActiveRecord::Base. Because defined? can return nil we ensure that nil
8
+ # becomes false.
9
+ defined?(::ActiveRecord) && defined?(::ActiveRecord::Base) &&
10
+ klass.ancestors.include?(::ActiveRecord::Base) || false
11
+ end
2
12
 
3
- def self.supports?(klass)
4
- # Some gems will declare an ActiveRecord module for their own purposes
5
- # so we can't assume because we have the ActiveRecord module that we also
6
- # have ActiveRecord::Base. Because defined? can return nil we ensure that nil
7
- # becomes false.
8
- defined?(ActiveRecord) && defined?(ActiveRecord::Base) && klass.ancestors.include?(ActiveRecord::Base) || false
9
- end
10
-
11
- def build_instance
12
- if _klass.respond_to?(:protected_attributes)
13
- self._instance = _klass.new(_attributes, without_protection: true)
14
- else
15
- self._instance = _klass.new(_attributes)
13
+ def build_instance
14
+ self._instance = if _klass.respond_to?(:protected_attributes)
15
+ _klass.new(_attributes, without_protection: true)
16
+ else
17
+ _klass.new(_attributes)
18
+ end
19
+ end
16
20
  end
17
21
  end
18
-
19
22
  end
@@ -1,103 +1,115 @@
1
- class Fabrication::Generator::Base
2
-
3
- def self.supports?(_klass); true end
1
+ module Fabrication
2
+ module Generator
3
+ class Base
4
+ def self.supports?(_klass)
5
+ true
6
+ end
4
7
 
5
- def build(attributes=[], callbacks={})
6
- process_attributes(attributes)
8
+ def build(attributes = [], callbacks = {})
9
+ process_attributes(attributes)
7
10
 
8
- if callbacks[:initialize_with]
9
- build_instance_with_constructor_override(callbacks[:initialize_with])
10
- elsif callbacks[:on_init]
11
- build_instance_with_init_callback(callbacks[:on_init])
12
- else
13
- build_instance
14
- end
15
- execute_callbacks(callbacks[:after_build])
16
- _instance
17
- end
11
+ if callbacks[:initialize_with]
12
+ build_instance_with_constructor_override(callbacks[:initialize_with])
13
+ elsif callbacks[:on_init]
14
+ build_instance_with_init_callback(callbacks[:on_init])
15
+ else
16
+ build_instance
17
+ end
18
+ execute_callbacks(callbacks[:after_build])
19
+ _instance
20
+ end
18
21
 
19
- def create(attributes=[], callbacks=[])
20
- build(attributes, callbacks)
21
- execute_callbacks(callbacks[:before_validation])
22
- execute_callbacks(callbacks[:after_validation])
23
- execute_callbacks(callbacks[:before_save])
24
- execute_callbacks(callbacks[:before_create])
25
- persist
26
- execute_callbacks(callbacks[:after_create])
27
- execute_callbacks(callbacks[:after_save])
28
- _instance
29
- end
22
+ def create(attributes = [], callbacks = [])
23
+ build(attributes, callbacks)
24
+ execute_callbacks(callbacks[:before_validation])
25
+ execute_callbacks(callbacks[:after_validation])
26
+ execute_callbacks(callbacks[:before_save])
27
+ execute_callbacks(callbacks[:before_create])
28
+ persist
29
+ execute_callbacks(callbacks[:after_create])
30
+ execute_callbacks(callbacks[:after_save])
31
+ _instance
32
+ end
30
33
 
31
- def execute_callbacks(callbacks)
32
- callbacks.each { |callback| _instance.instance_exec(_instance, _transient_attributes, &callback) } if callbacks
33
- end
34
+ def execute_callbacks(callbacks)
35
+ callbacks&.each { |callback| _instance.instance_exec(_instance, _transient_attributes, &callback) }
36
+ end
34
37
 
35
- def to_params(attributes=[])
36
- process_attributes(attributes)
37
- _attributes.respond_to?(:with_indifferent_access) ? _attributes.with_indifferent_access : _attributes
38
- end
38
+ def to_params(attributes = [])
39
+ process_attributes(attributes)
40
+ _attributes.respond_to?(:with_indifferent_access) ? _attributes.with_indifferent_access : _attributes
41
+ end
39
42
 
40
- def to_hash(attributes=[], callbacks=[])
41
- process_attributes(attributes)
42
- Fabrication::Support.hash_class.new.tap do |hash|
43
- _attributes.map do |name, value|
44
- if value && value.respond_to?(:id)
45
- hash["#{name}_id"] = value.id
46
- else
47
- hash[name] = value
43
+ def to_hash(attributes = [], _callbacks = [])
44
+ process_attributes(attributes)
45
+ Fabrication::Support.hash_class.new.tap do |hash|
46
+ _attributes.map do |name, value|
47
+ if value.respond_to?(:id)
48
+ hash["#{name}_id"] = value.id
49
+ else
50
+ hash[name] = value
51
+ end
52
+ end
48
53
  end
49
54
  end
50
- end
51
- end
52
55
 
53
- def build_instance_with_constructor_override(callback)
54
- self._instance = instance_eval(&callback)
55
- set_attributes
56
- end
56
+ def build_instance_with_constructor_override(callback)
57
+ self._instance = instance_eval(&callback)
58
+ set_attributes
59
+ end
57
60
 
58
- def build_instance_with_init_callback(callback)
59
- self._instance = _klass.new(*callback.call)
60
- set_attributes
61
- end
61
+ def build_instance_with_init_callback(callback)
62
+ self._instance = _klass.new(*callback.call)
63
+ set_attributes
64
+ end
62
65
 
63
- def build_instance
64
- self._instance = _klass.new
65
- set_attributes
66
- end
66
+ def build_instance
67
+ self._instance = _klass.new
68
+ set_attributes
69
+ end
67
70
 
68
- def set_attributes
69
- _attributes.each do |k,v|
70
- _instance.send("#{k}=", v)
71
- end
72
- end
71
+ def set_attributes
72
+ if _instance.respond_to?(:attributes=)
73
+ _instance.attributes = _attributes
74
+ else
75
+ _attributes.each do |k, v|
76
+ _instance.send("#{k}=", v)
77
+ end
78
+ end
79
+ end
73
80
 
74
- def initialize(klass)
75
- self._klass = klass
76
- end
81
+ def initialize(klass)
82
+ self._klass = klass
83
+ end
77
84
 
78
- def method_missing(method_name, *args, &block)
79
- _attributes[method_name] || super
80
- end
85
+ def respond_to_missing?(method_name, _include_private = false)
86
+ _attributes.key?(method_name)
87
+ end
81
88
 
82
- protected
89
+ def method_missing(method_name, *args, &block)
90
+ _attributes.fetch(method_name) { super }
91
+ end
83
92
 
84
- attr_accessor :_klass, :_instance, :_transient_attributes
93
+ protected
85
94
 
86
- def _attributes
87
- @_attributes ||= {}
88
- end
95
+ attr_accessor :_klass, :_instance, :_transient_attributes
89
96
 
90
- def persist
91
- _instance.save! if _instance.respond_to?(:save!)
92
- end
97
+ def _attributes
98
+ @_attributes ||= {}
99
+ end
93
100
 
94
- def process_attributes(attributes)
95
- self._transient_attributes = Hash.new
96
- attributes.each do |attribute|
97
- _attributes[attribute.name] = attribute.processed_value(_attributes)
98
- _transient_attributes[attribute.name] = _attributes[attribute.name] if attribute.transient?
101
+ def persist
102
+ _instance.save! if _instance.respond_to?(:save!)
103
+ end
104
+
105
+ def process_attributes(attributes)
106
+ self._transient_attributes = ({})
107
+ attributes.each do |attribute|
108
+ _attributes[attribute.name] = attribute.processed_value(_attributes)
109
+ _transient_attributes[attribute.name] = _attributes[attribute.name] if attribute.transient?
110
+ end
111
+ _attributes.reject! { |k| _transient_attributes.keys.include?(k) }
112
+ end
99
113
  end
100
- _attributes.reject! { |k| _transient_attributes.keys.include?(k) }
101
114
  end
102
-
103
115
  end