dataset 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +59 -0
- data/LICENSE +19 -0
- data/README +111 -0
- data/Rakefile +31 -0
- data/TODO +15 -0
- data/VERSION.yml +4 -0
- data/lib/dataset.rb +128 -0
- data/lib/dataset/base.rb +157 -0
- data/lib/dataset/collection.rb +19 -0
- data/lib/dataset/database/base.rb +30 -0
- data/lib/dataset/database/mysql.rb +34 -0
- data/lib/dataset/database/postgresql.rb +34 -0
- data/lib/dataset/database/sqlite3.rb +32 -0
- data/lib/dataset/extensions/cucumber.rb +20 -0
- data/lib/dataset/extensions/rspec.rb +21 -0
- data/lib/dataset/extensions/test_unit.rb +60 -0
- data/lib/dataset/instance_methods.rb +10 -0
- data/lib/dataset/load.rb +47 -0
- data/lib/dataset/record/fixture.rb +73 -0
- data/lib/dataset/record/meta.rb +66 -0
- data/lib/dataset/record/model.rb +50 -0
- data/lib/dataset/resolver.rb +110 -0
- data/lib/dataset/session.rb +51 -0
- data/lib/dataset/session_binding.rb +317 -0
- data/lib/dataset/version.rb +9 -0
- data/plugit/descriptor.rb +25 -0
- data/spec/dataset/cucumber_spec.rb +54 -0
- data/spec/dataset/database/base_spec.rb +21 -0
- data/spec/dataset/record/meta_spec.rb +14 -0
- data/spec/dataset/resolver_spec.rb +110 -0
- data/spec/dataset/rspec_spec.rb +133 -0
- data/spec/dataset/session_binding_spec.rb +198 -0
- data/spec/dataset/session_spec.rb +299 -0
- data/spec/dataset/test_unit_spec.rb +210 -0
- data/spec/fixtures/datasets/constant_not_defined.rb +0 -0
- data/spec/fixtures/datasets/ending_with_dataset.rb +2 -0
- data/spec/fixtures/datasets/exact_name.rb +2 -0
- data/spec/fixtures/datasets/not_a_dataset_base.rb +2 -0
- data/spec/fixtures/more_datasets/in_another_directory.rb +2 -0
- data/spec/models.rb +18 -0
- data/spec/schema.rb +26 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/stubs/mini_rails.rb +18 -0
- data/spec/stubs/test_help.rb +1 -0
- data/tasks/dataset.rake +19 -0
- metadata +120 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
module Dataset
|
2
|
+
module Record # :nodoc:
|
3
|
+
|
4
|
+
class Model # :nodoc:
|
5
|
+
attr_reader :attributes, :model, :meta, :symbolic_name, :session_binding
|
6
|
+
|
7
|
+
def initialize(meta, attributes, symbolic_name, session_binding)
|
8
|
+
@meta = meta
|
9
|
+
@attributes = attributes.stringify_keys
|
10
|
+
@symbolic_name = symbolic_name || object_id
|
11
|
+
@session_binding = session_binding
|
12
|
+
end
|
13
|
+
|
14
|
+
def record_class
|
15
|
+
meta.record_class
|
16
|
+
end
|
17
|
+
|
18
|
+
def id
|
19
|
+
model.id
|
20
|
+
end
|
21
|
+
|
22
|
+
def create
|
23
|
+
model = to_model
|
24
|
+
model.save!
|
25
|
+
model
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_hash
|
29
|
+
to_model.attributes
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_model
|
33
|
+
@model ||= begin
|
34
|
+
m = meta.record_class.new
|
35
|
+
attributes.each do |k,v|
|
36
|
+
if reflection = record_class.reflect_on_association(k.to_sym)
|
37
|
+
case v
|
38
|
+
when Symbol
|
39
|
+
v = session_binding.find_model(reflection.klass, v)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
m.send "#{k}=", v
|
43
|
+
end
|
44
|
+
m
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Dataset
|
2
|
+
# An error raised when a dataset class cannot be found.
|
3
|
+
#
|
4
|
+
class DatasetNotFound < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
# A dataset may be referenced as a class or as a name. A Dataset::Resolver
|
8
|
+
# will take an identifier, whether a class or a name, and return the class.
|
9
|
+
#
|
10
|
+
class Resolver
|
11
|
+
cattr_accessor :default
|
12
|
+
|
13
|
+
def identifiers
|
14
|
+
@identifiers ||= {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Attempt to convert a name to a constant. With the identifier :people, it
|
18
|
+
# will search for 'PeopleDataset', then 'People'.
|
19
|
+
#
|
20
|
+
def resolve(identifier)
|
21
|
+
return identifier if identifier.is_a?(Class)
|
22
|
+
if constant = identifiers[identifier]
|
23
|
+
return constant
|
24
|
+
end
|
25
|
+
|
26
|
+
constant = resolve_class(identifier)
|
27
|
+
unless constant
|
28
|
+
constant = resolve_identifier(identifier)
|
29
|
+
end
|
30
|
+
identifiers[identifier] = constant
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
def resolve_identifier(identifier) # :nodoc:
|
35
|
+
constant = resolve_class(identifier)
|
36
|
+
unless constant
|
37
|
+
raise Dataset::DatasetNotFound, "Could not find a dataset '#{identifier.to_s.camelize}' or '#{identifier.to_s.camelize + suffix}'."
|
38
|
+
end
|
39
|
+
constant
|
40
|
+
end
|
41
|
+
|
42
|
+
def resolve_class(identifier)
|
43
|
+
names = [identifier.to_s.camelize, identifier.to_s.camelize + suffix]
|
44
|
+
constant = resolve_these(names.reverse)
|
45
|
+
if constant && constant.superclass != ::Dataset::Base
|
46
|
+
raise Dataset::DatasetNotFound, "Found a class '#{constant.name}', but it does not subclass 'Dataset::Base'."
|
47
|
+
end
|
48
|
+
constant
|
49
|
+
end
|
50
|
+
|
51
|
+
def resolve_these(names) # :nodoc:
|
52
|
+
names.each do |name|
|
53
|
+
constant = name.constantize rescue nil
|
54
|
+
return constant if constant && constant.is_a?(Class)
|
55
|
+
end
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def suffix # :nodoc:
|
60
|
+
@suffix ||= 'Dataset'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Resolves a dataset by looking for a file in the provided directory path
|
65
|
+
# that has a name matching the identifier. Of course, should the identifier
|
66
|
+
# be a class already, it is simply returned.
|
67
|
+
#
|
68
|
+
class DirectoryResolver < Resolver
|
69
|
+
def initialize(*paths)
|
70
|
+
@paths = paths
|
71
|
+
end
|
72
|
+
|
73
|
+
def <<(path)
|
74
|
+
@paths << path
|
75
|
+
end
|
76
|
+
|
77
|
+
protected
|
78
|
+
def resolve_identifier(identifier) # :nodoc:
|
79
|
+
@paths.each do |path|
|
80
|
+
file = File.join(path, identifier.to_s)
|
81
|
+
unless File.exists?(file + '.rb')
|
82
|
+
file = file + '_' + file_suffix
|
83
|
+
next unless File.exists?(file + '.rb')
|
84
|
+
end
|
85
|
+
require file
|
86
|
+
begin
|
87
|
+
return super
|
88
|
+
rescue Dataset::DatasetNotFound => dnf
|
89
|
+
if dnf.message =~ /\ACould not find/
|
90
|
+
raise Dataset::DatasetNotFound, "Found the dataset file '#{file + '.rb'}', but it did not define #{dnf.message.sub('Could not find ', '')}"
|
91
|
+
else
|
92
|
+
raise Dataset::DatasetNotFound, "Found the dataset file '#{file + '.rb'}' and a class #{dnf.message.sub('Found a class ', '')}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
raise DatasetNotFound, "Could not find a dataset file in #{@paths.inspect} having the name '#{identifier}.rb' or '#{identifier}_#{file_suffix}.rb'."
|
97
|
+
end
|
98
|
+
|
99
|
+
def file_suffix # :nodoc:
|
100
|
+
@file_suffix ||= suffix.downcase
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# The default resolver, used by the Dataset::Sessions that aren't given a
|
105
|
+
# different instance. You can set this to something else in your
|
106
|
+
# test/spec_helper.
|
107
|
+
#
|
108
|
+
Resolver.default = Resolver.new
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Dataset
|
2
|
+
class Session # :nodoc:
|
3
|
+
attr_accessor :dataset_resolver
|
4
|
+
|
5
|
+
def initialize(database, dataset_resolver = Resolver.default)
|
6
|
+
@database = database
|
7
|
+
@dataset_resolver = dataset_resolver
|
8
|
+
@datasets = Hash.new
|
9
|
+
@load_stack = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_dataset(test_class, dataset_identifier)
|
13
|
+
dataset = dataset_resolver.resolve(dataset_identifier)
|
14
|
+
if dataset.used_datasets
|
15
|
+
dataset.used_datasets.each { |used_dataset| self.add_dataset(test_class, used_dataset) }
|
16
|
+
end
|
17
|
+
datasets_for(test_class) << dataset
|
18
|
+
end
|
19
|
+
|
20
|
+
def datasets_for(test_class)
|
21
|
+
if test_class.superclass
|
22
|
+
@datasets[test_class] ||= Collection.new(datasets_for(test_class.superclass) || [])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_datasets_for(test_class)
|
27
|
+
datasets = datasets_for(test_class)
|
28
|
+
if last_load = @load_stack.last
|
29
|
+
if last_load.datasets == datasets
|
30
|
+
current_load = Reload.new(last_load)
|
31
|
+
elsif last_load.datasets.subset?(datasets)
|
32
|
+
@database.capture(last_load.datasets)
|
33
|
+
current_load = Load.new(datasets, last_load.dataset_binding)
|
34
|
+
current_load.execute(last_load.datasets, @dataset_resolver)
|
35
|
+
@load_stack.push(current_load)
|
36
|
+
else
|
37
|
+
@load_stack.pop
|
38
|
+
last_load = @load_stack.last
|
39
|
+
@database.restore(last_load.datasets) if last_load
|
40
|
+
current_load = load_datasets_for(test_class)
|
41
|
+
end
|
42
|
+
else
|
43
|
+
@database.clear
|
44
|
+
current_load = Load.new(datasets, @database)
|
45
|
+
current_load.execute([], @dataset_resolver)
|
46
|
+
@load_stack.push(current_load)
|
47
|
+
end
|
48
|
+
current_load
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,317 @@
|
|
1
|
+
module Dataset
|
2
|
+
# An error that will be raised when an attempt is made to load a named model
|
3
|
+
# that doesn't exist. For example, if you do people(:jenny), and yet no
|
4
|
+
# record was ever created with the symbolic name :jenny, this error will be
|
5
|
+
# raised.
|
6
|
+
#
|
7
|
+
class RecordNotFound < StandardError
|
8
|
+
def initialize(record_type, symbolic_name)
|
9
|
+
super "There is no '#{record_type.name}' found for the symbolic name ':#{symbolic_name}'."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Whenever you use Dataset::RecordMethods, you will get finder methods in
|
14
|
+
# your tests that help you load instances of the records you have created
|
15
|
+
# (or named models).
|
16
|
+
#
|
17
|
+
# create_record :person, :jimmy, :name => 'Jimmy'
|
18
|
+
# person_id(:jimmy) => The id was captured from create_record
|
19
|
+
# people(:jimmy) => The same as Jimmy.find(person_id(:jimmy))
|
20
|
+
#
|
21
|
+
# The methods will not exist in a test unless it utilizes a dataset (or
|
22
|
+
# defines one itself through the block technique) that creates a record for
|
23
|
+
# the type.
|
24
|
+
#
|
25
|
+
# You may also pass multiple names to these methods, which will have them
|
26
|
+
# return an array of values.
|
27
|
+
#
|
28
|
+
# people(:jimmy, :jane, :jeff) => [<# Person :name => 'Jimmy'>, <# Person :name => 'Jane'>, <# Person :name => 'Jeff'>]
|
29
|
+
# person_id(:jimmy, :jane, :jeff) => [1, 2, 3]
|
30
|
+
#
|
31
|
+
# NOTE the plurality of the instance finder, versus the singularity of the
|
32
|
+
# id finder.
|
33
|
+
#
|
34
|
+
# == Single Table Inheritence
|
35
|
+
#
|
36
|
+
# class Person < ActiveRecord::Base; end
|
37
|
+
# class User < Person; end
|
38
|
+
#
|
39
|
+
# create_record :user, :bobby, :name => 'Bobby'
|
40
|
+
#
|
41
|
+
# people(:bobby) OR users(:bobby)
|
42
|
+
#
|
43
|
+
module ModelFinders
|
44
|
+
def create_finder(record_meta) # :nodoc:
|
45
|
+
@finders_generated ||= []
|
46
|
+
|
47
|
+
return if @finders_generated.include?(record_meta)
|
48
|
+
|
49
|
+
record_meta.model_finder_names.each do |finder_name|
|
50
|
+
unless instance_methods.include?(finder_name)
|
51
|
+
define_method finder_name do |*symbolic_names|
|
52
|
+
names = Array(symbolic_names)
|
53
|
+
models = names.inject([]) do |c,n|
|
54
|
+
c << dataset_session_binding.find_model(record_meta, n); c
|
55
|
+
end
|
56
|
+
names.size == 1 ? models.first : models
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
record_meta.id_finder_names.each do |finder_name|
|
62
|
+
unless instance_methods.include?(finder_name)
|
63
|
+
define_method finder_name do |*symbolic_names|
|
64
|
+
names = Array(symbolic_names)
|
65
|
+
ids = names.inject([]) do |c,n|
|
66
|
+
c << dataset_session_binding.find_id(record_meta, n); c
|
67
|
+
end
|
68
|
+
names.size == 1 ? ids.first : ids
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
@finders_generated << record_meta
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Any Dataset::Base subclass, dataset block, or test method in a
|
78
|
+
# dataset-using test context (including setup/teardown/before/after) may
|
79
|
+
# create and access models through these methods. Note that you should use
|
80
|
+
# Dataset::ModelFinders if you can for finding your created data.
|
81
|
+
#
|
82
|
+
module RecordMethods
|
83
|
+
|
84
|
+
# Similar to old fashioned fixtures, this will do a direct database
|
85
|
+
# insert, without running any validations or preventing you from writing
|
86
|
+
# attr_protected attributes. Very nice for speed, but kind of a pain if
|
87
|
+
# you have complex structures or hard to keep right validations.
|
88
|
+
#
|
89
|
+
# create_record :type, :symbolic_name, :attr1 => 'value', :attr2 => 'value', :etc => 'etc'
|
90
|
+
#
|
91
|
+
# The _symbolic_name_ is an optional parameter. You may replace _type_
|
92
|
+
# with an ActiveRecord::Base subclass or anything that works with:
|
93
|
+
#
|
94
|
+
# to_s.classify.constantize
|
95
|
+
#
|
96
|
+
# The id of the model will be a hash of the symbolic name.
|
97
|
+
#
|
98
|
+
def create_record(*args)
|
99
|
+
dataset_session_binding.create_record(*args)
|
100
|
+
end
|
101
|
+
|
102
|
+
# This will instantiate your model class and assign each attribute WITHOUT
|
103
|
+
# using mass assignment. Validations will be run. Very nice for complex
|
104
|
+
# structures or hard to keep right validations, but potentially a bit
|
105
|
+
# slower, since it runs through all that ActiveRecord code.
|
106
|
+
#
|
107
|
+
# create_model :type, :symbolic_name, :attr1 => 'value', :attr2 => 'value', :etc => 'etc'
|
108
|
+
#
|
109
|
+
# The _symbolic_name_ is an optional parameter. You may replace _type_
|
110
|
+
# with an ActiveRecord::Base subclass or anything that works with:
|
111
|
+
#
|
112
|
+
# to_s.classify.constantize
|
113
|
+
#
|
114
|
+
# The id of the record will be kept from the instance that is saved.
|
115
|
+
#
|
116
|
+
def create_model(*args)
|
117
|
+
dataset_session_binding.create_model(*args)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Dataset will track each of the records it creates by symbolic name to
|
121
|
+
# id. When you need the id of a record, there is no need to go to the
|
122
|
+
# database.
|
123
|
+
#
|
124
|
+
# find_id :person, :bobby => 23425234
|
125
|
+
#
|
126
|
+
# You may pass one name or many, with many returning an Array of ids.
|
127
|
+
#
|
128
|
+
def find_id(*args)
|
129
|
+
dataset_session_binding.find_id(*args)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Dataset will track each of the records it creates by symbolic name to
|
133
|
+
# id. When you need an instance of a record, the stored id will be used to
|
134
|
+
# do the fastest lookup possible: Person.find(23425234).
|
135
|
+
#
|
136
|
+
# find_model :person, :bobby => <#Person :id => 23425234, :name => 'Bobby'>
|
137
|
+
#
|
138
|
+
# You may pass one name or many, with many returning an Array of
|
139
|
+
# instances.
|
140
|
+
#
|
141
|
+
def find_model(*args)
|
142
|
+
dataset_session_binding.find_model(*args)
|
143
|
+
end
|
144
|
+
|
145
|
+
# This is a great help when you want to create records in a custom helper
|
146
|
+
# method, then make it and maybe things associated to it available to
|
147
|
+
# tests through the Dataset::ModelFinders.
|
148
|
+
#
|
149
|
+
# thingy = create_very_complex_thingy_and_stuff
|
150
|
+
# name_model thingy, :thingy_bob
|
151
|
+
# name_model thingy.part, :thingy_part
|
152
|
+
#
|
153
|
+
# In tests:
|
154
|
+
#
|
155
|
+
# thingies(:thingy_bob)
|
156
|
+
# parts(:thingy_part)
|
157
|
+
#
|
158
|
+
def name_model(*args)
|
159
|
+
dataset_session_binding.name_model(*args)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Converts string names into symbols for use in naming models
|
163
|
+
#
|
164
|
+
# name_to_sym 'my name' => :my_name
|
165
|
+
# name_to_sym 'RPaul' => :r_paul
|
166
|
+
#
|
167
|
+
def name_to_sym(name)
|
168
|
+
dataset_session_binding.name_to_sym(name)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class SessionBinding # :nodoc:
|
173
|
+
attr_reader :database, :parent_binding
|
174
|
+
attr_reader :model_finders, :record_methods
|
175
|
+
attr_reader :block_variables
|
176
|
+
|
177
|
+
def initialize(database_or_parent_binding)
|
178
|
+
@id_cache = Hash.new {|h,k| h[k] = {}}
|
179
|
+
@record_methods = new_record_methods_module
|
180
|
+
@model_finders = new_model_finders_module
|
181
|
+
@block_variables = Hash.new
|
182
|
+
|
183
|
+
case database_or_parent_binding
|
184
|
+
when Dataset::SessionBinding
|
185
|
+
@parent_binding = database_or_parent_binding
|
186
|
+
@database = parent_binding.database
|
187
|
+
@model_finders.module_eval { include database_or_parent_binding.model_finders }
|
188
|
+
@block_variables.update(database_or_parent_binding.block_variables)
|
189
|
+
else
|
190
|
+
@database = database_or_parent_binding
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def copy_block_variables(dataset_block)
|
195
|
+
dataset_block.instance_variables.each do |name|
|
196
|
+
self.block_variables[name] = dataset_block.instance_variable_get(name)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def create_model(record_type, *args)
|
201
|
+
insert(Dataset::Record::Model, record_type, *args)
|
202
|
+
end
|
203
|
+
|
204
|
+
def create_record(record_type, *args)
|
205
|
+
insert(Dataset::Record::Fixture, record_type, *args)
|
206
|
+
end
|
207
|
+
|
208
|
+
def find_id(record_type_or_meta, symbolic_name)
|
209
|
+
record_meta = record_meta_for_type(record_type_or_meta)
|
210
|
+
if local_id = @id_cache[record_meta.id_cache_key][symbolic_name]
|
211
|
+
local_id
|
212
|
+
elsif !parent_binding.nil?
|
213
|
+
parent_binding.find_id record_meta, symbolic_name
|
214
|
+
else
|
215
|
+
raise RecordNotFound.new(record_meta, symbolic_name)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def find_model(record_type_or_meta, symbolic_name)
|
220
|
+
record_meta = record_meta_for_type(record_type_or_meta)
|
221
|
+
if local_id = @id_cache[record_meta.id_cache_key][symbolic_name]
|
222
|
+
record_meta.record_class.find local_id
|
223
|
+
elsif !parent_binding.nil?
|
224
|
+
parent_binding.find_model record_meta, symbolic_name
|
225
|
+
else
|
226
|
+
raise RecordNotFound.new(record_meta, symbolic_name)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def install_block_variables(target)
|
231
|
+
block_variables.each do |k,v|
|
232
|
+
target.instance_variable_set(k,v)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def name_model(record, symbolic_name)
|
237
|
+
record_meta = database.record_meta(record.class)
|
238
|
+
@model_finders.create_finder(record_meta)
|
239
|
+
@id_cache[record_meta.id_cache_key][symbolic_name] = record.id
|
240
|
+
record
|
241
|
+
end
|
242
|
+
|
243
|
+
def record_meta_for_type(record_type)
|
244
|
+
record_type.is_a?(Record::Meta) ? record_type : begin
|
245
|
+
record_class = resolve_record_class(record_type)
|
246
|
+
database.record_meta(record_class)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def name_to_sym(name)
|
251
|
+
name.to_s.underscore.gsub("'", "").gsub("\"", "").gsub(" ", "_").to_sym if name
|
252
|
+
end
|
253
|
+
|
254
|
+
protected
|
255
|
+
def insert(dataset_record_class, record_type, *args)
|
256
|
+
symbolic_name, attributes = extract_creation_arguments args
|
257
|
+
record_meta = record_meta_for_type(record_type)
|
258
|
+
record = dataset_record_class.new(record_meta, attributes, symbolic_name, self)
|
259
|
+
return_value = nil
|
260
|
+
|
261
|
+
@model_finders.create_finder(record_meta)
|
262
|
+
ActiveRecord::Base.silence do
|
263
|
+
return_value = record.create
|
264
|
+
@id_cache[record_meta.id_cache_key][symbolic_name] = record.id
|
265
|
+
end
|
266
|
+
return_value
|
267
|
+
end
|
268
|
+
|
269
|
+
def extract_creation_arguments(arguments)
|
270
|
+
if arguments.size == 2 && arguments.last.kind_of?(Hash)
|
271
|
+
arguments
|
272
|
+
elsif arguments.size == 1 && arguments.last.kind_of?(Hash)
|
273
|
+
[nil, arguments.last]
|
274
|
+
elsif arguments.size == 1 && arguments.last.kind_of?(Symbol)
|
275
|
+
[arguments.last, Hash.new]
|
276
|
+
else
|
277
|
+
[nil, Hash.new]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def new_model_finders_module
|
282
|
+
mod = Module.new
|
283
|
+
dataset_binding = self
|
284
|
+
mod.module_eval do
|
285
|
+
define_method :dataset_session_binding do
|
286
|
+
dataset_binding
|
287
|
+
end
|
288
|
+
end
|
289
|
+
mod.extend ModelFinders
|
290
|
+
mod
|
291
|
+
end
|
292
|
+
|
293
|
+
def new_record_methods_module
|
294
|
+
mod = Module.new do
|
295
|
+
include RecordMethods
|
296
|
+
end
|
297
|
+
dataset_binding = self
|
298
|
+
mod.module_eval do
|
299
|
+
define_method :dataset_session_binding do
|
300
|
+
dataset_binding
|
301
|
+
end
|
302
|
+
end
|
303
|
+
mod
|
304
|
+
end
|
305
|
+
|
306
|
+
def resolve_record_class(record_type)
|
307
|
+
case record_type
|
308
|
+
when Symbol
|
309
|
+
resolve_record_class record_type.to_s.singularize.camelize
|
310
|
+
when Class
|
311
|
+
record_type
|
312
|
+
when String
|
313
|
+
record_type.constantize
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|