fabrication 2.21.0 → 3.0.0.beta.1.1

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.
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