dm-accepts_nested_attributes 0.12.0 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +145 -0
- data/Rakefile +6 -11
- data/VERSION +1 -0
- data/dm-accepts_nested_attributes.gemspec +18 -17
- data/lib/dm-accepts_nested_attributes/model.rb +0 -38
- data/spec/accepts_nested_attributes_for_spec.rb +4 -4
- data/spec/many_to_many_spec.rb +5 -5
- data/spec/many_to_one_spec.rb +3 -3
- data/spec/one_to_many_spec.rb +3 -3
- data/spec/one_to_one_spec.rb +4 -4
- data/spec/shared/many_to_many_spec.rb +35 -51
- data/spec/shared/many_to_one_spec.rb +5 -25
- data/spec/shared/one_to_many_spec.rb +0 -21
- data/spec/shared/one_to_one_spec.rb +0 -19
- data/spec/spec_helper.rb +17 -33
- data/tasks/local_gemfile.rake +18 -0
- data/tasks/spec.rake +0 -3
- metadata +58 -25
- data/lib/dm-accepts_nested_attributes/error_collecting.rb +0 -35
- data/lib/dm-accepts_nested_attributes/transactional_save.rb +0 -24
data/.gitignore
CHANGED
data/Gemfile
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
# If you're working on more than one datamapper gem at a time, then it's
|
2
|
+
# recommended to create a local Gemfile and use this instead of the git
|
3
|
+
# sources. This will make sure that you are developing against your
|
4
|
+
# other local datamapper sources that you currently work on. Gemfile.local
|
5
|
+
# will behave identically to the standard Gemfile apart from the fact that
|
6
|
+
# it fetches the datamapper gems from local paths. This means that you can use
|
7
|
+
# the same environment variables, like ADAPTER(S) or PLUGIN(S) when running
|
8
|
+
# bundle commands. Gemfile.local is added to .gitignore, so you don't need to
|
9
|
+
# worry about accidentally checking local development paths into git.
|
10
|
+
# In order to create a local Gemfile, all you need to do is run:
|
11
|
+
#
|
12
|
+
# bundle exec rake local_gemfile
|
13
|
+
#
|
14
|
+
# This will give you a Gemfile.local file that points to your local clones of
|
15
|
+
# the various datamapper gems. It's assumed that all datamapper repo clones
|
16
|
+
# reside in the same directory. You can use the Gemfile.local like so for
|
17
|
+
# running any bundle command:
|
18
|
+
#
|
19
|
+
# BUNDLE_GEMFILE=Gemfile.local bundle foo
|
20
|
+
#
|
21
|
+
# You can also specify which adapter(s) should be part of the bundle by setting
|
22
|
+
# an environment variable. This of course also works when using the Gemfile.local
|
23
|
+
#
|
24
|
+
# bundle foo # dm-sqlite-adapter
|
25
|
+
# ADAPTER=mysql bundle foo # dm-mysql-adapter
|
26
|
+
# ADAPTERS=sqlite,mysql bundle foo # dm-sqlite-adapter and dm-mysql-adapter
|
27
|
+
#
|
28
|
+
# Of course you can also use the ADAPTER(S) variable when using the Gemfile.local
|
29
|
+
# and running specs against selected adapters.
|
30
|
+
#
|
31
|
+
# For easily working with adapters supported on your machine, it's recommended
|
32
|
+
# that you first install all adapters that you are planning to use or work on
|
33
|
+
# by doing something like
|
34
|
+
#
|
35
|
+
# ADAPTERS=sqlite,mysql,postgres bundle install
|
36
|
+
#
|
37
|
+
# This will clone the various repositories and make them available to bundler.
|
38
|
+
# Once you have them installed you can easily switch between adapters for the
|
39
|
+
# various development tasks. Running something like
|
40
|
+
#
|
41
|
+
# ADAPTER=mysql bundle exec rake spec
|
42
|
+
#
|
43
|
+
# will make sure that the dm-mysql-adapter is part of the bundle, and will be used
|
44
|
+
# when running the specs.
|
45
|
+
#
|
46
|
+
# You can also specify which plugin(s) should be part of the bundle by setting
|
47
|
+
# an environment variable. This also works when using the Gemfile.local
|
48
|
+
#
|
49
|
+
# bundle foo # dm-migrations
|
50
|
+
# PLUGINS=dm-validations bundle foo # dm-migrations and dm-validations
|
51
|
+
# PLUGINS=dm-validations,dm-types bundle foo # dm-migrations, dm-validations and dm-types
|
52
|
+
#
|
53
|
+
# Of course you can combine the PLUGIN(S) and ADAPTER(S) env vars to run specs
|
54
|
+
# for certain adapter/plugin combinations.
|
55
|
+
#
|
56
|
+
# Finally, to speed up running specs and other tasks, it's recommended to run
|
57
|
+
#
|
58
|
+
# bundle lock
|
59
|
+
#
|
60
|
+
# after running 'bundle install' for the first time. This will make 'bundle exec' run
|
61
|
+
# a lot faster compared to the unlocked version. With an unlocked bundle you would
|
62
|
+
# typically just run 'bundle install' from time to time to fetch the latest sources from
|
63
|
+
# upstream. When you locked your bundle, you need to run
|
64
|
+
#
|
65
|
+
# bundle install --relock
|
66
|
+
#
|
67
|
+
# to make sure to fetch the latest updates and then lock the bundle again. Gemfile.lock
|
68
|
+
# is added to the .gitignore file, so you don't need to worry about accidentally checking
|
69
|
+
# it into version control.
|
70
|
+
|
71
|
+
source 'http://rubygems.org'
|
72
|
+
|
73
|
+
DATAMAPPER = 'git://github.com/datamapper'
|
74
|
+
DM_VERSION = '~> 1.0.0.rc1'
|
75
|
+
|
76
|
+
|
77
|
+
group :runtime do # Runtime dependencies (as in the gemspec)
|
78
|
+
|
79
|
+
if ENV['EXTLIB']
|
80
|
+
gem 'extlib', '~> 0.9.15', :git => "#{DATAMAPPER}/extlib.git"
|
81
|
+
else
|
82
|
+
gem 'activesupport', '~> 3.0.0.beta3', :git => 'git://github.com/rails/rails.git', :require => nil
|
83
|
+
end
|
84
|
+
|
85
|
+
gem 'dm-core', DM_VERSION, :git => "#{DATAMAPPER}/dm-core.git"
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
group(:development) do # Development dependencies (as in the gemspec)
|
90
|
+
|
91
|
+
gem 'dm-validations', DM_VERSION, :git => "#{DATAMAPPER}/dm-validations.git"
|
92
|
+
gem 'dm-constraints', DM_VERSION, :git => "#{DATAMAPPER}/dm-constraints.git"
|
93
|
+
|
94
|
+
gem 'rake', '~> 0.8.7'
|
95
|
+
gem 'rspec', '~> 1.3'
|
96
|
+
gem 'yard', '~> 0.5'
|
97
|
+
gem 'rcov', '~> 0.9.7'
|
98
|
+
gem 'jeweler', '~> 1.4'
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
group :quality do # These gems contain rake tasks that check the quality of the source code
|
103
|
+
|
104
|
+
gem 'yardstick', '~> 0.1'
|
105
|
+
gem 'metric_fu', '~> 1.3'
|
106
|
+
gem 'reek', '~> 1.2.7'
|
107
|
+
gem 'roodi', '~> 2.1'
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
group :datamapper do # We need this because we want to pin these dependencies to their git master sources
|
112
|
+
|
113
|
+
adapters = ENV['ADAPTER'] || ENV['ADAPTERS']
|
114
|
+
adapters = adapters.to_s.gsub(',',' ').split(' ') - ['in_memory']
|
115
|
+
|
116
|
+
unless adapters.empty?
|
117
|
+
|
118
|
+
DO_VERSION = '~> 0.10.2'
|
119
|
+
DM_DO_ADAPTERS = %w[sqlite postgres mysql oracle sqlserver]
|
120
|
+
|
121
|
+
gem 'data_objects', DO_VERSION, :git => "#{DATAMAPPER}/do.git"
|
122
|
+
|
123
|
+
adapters.each do |adapter|
|
124
|
+
if DM_DO_ADAPTERS.any? { |dm_do_adapter| dm_do_adapter =~ /#{adapter}/ }
|
125
|
+
adapter = 'sqlite3' if adapter == 'sqlite'
|
126
|
+
gem "do_#{adapter}", DO_VERSION, :git => "#{DATAMAPPER}/do.git"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
gem 'dm-do-adapter', DM_VERSION, :git => "#{DATAMAPPER}/dm-do-adapter.git"
|
131
|
+
|
132
|
+
adapters.each do |adapter|
|
133
|
+
gem "dm-#{adapter}-adapter", DM_VERSION, :git => "#{DATAMAPPER}/dm-#{adapter}-adapter.git"
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
plugins = ENV['PLUGINS'] || ENV['PLUGIN']
|
139
|
+
plugins = (plugins.to_s.gsub(',',' ').split(' ') + ['dm-migrations']).uniq
|
140
|
+
|
141
|
+
plugins.each do |plugin|
|
142
|
+
gem plugin, DM_VERSION, :git => "#{DATAMAPPER}/#{plugin}.git"
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
data/Rakefile
CHANGED
@@ -1,35 +1,30 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
|
4
|
-
require File.expand_path('../lib/dm-accepts_nested_attributes/version', __FILE__)
|
5
|
-
|
6
|
-
FileList['tasks/**/*.rake'].each { |task| load task }
|
7
|
-
|
8
4
|
begin
|
9
5
|
|
10
|
-
gem 'jeweler', '~> 1.4'
|
11
6
|
require 'jeweler'
|
12
7
|
|
13
8
|
Jeweler::Tasks.new do |gem|
|
14
9
|
|
15
|
-
gem.version = DataMapper::NestedAttributes::VERSION
|
16
|
-
|
17
10
|
gem.name = 'dm-accepts_nested_attributes'
|
18
11
|
gem.summary = 'Nested model assignment for datamapper'
|
19
12
|
gem.description = 'A datamapper plugin that allows nested model assignment like activerecord.'
|
20
13
|
gem.email = 'gamsnjaga [a] gmail [d] com'
|
21
14
|
gem.homepage = 'http://github.com/snusnu/dm-accepts_nested_attributes'
|
22
|
-
gem.authors = [ 'Martin Gamsjaeger' ]
|
15
|
+
gem.authors = [ 'Martin Gamsjaeger (snusnu)' ]
|
23
16
|
|
24
|
-
gem.add_dependency
|
17
|
+
gem.add_dependency 'dm-core', '~> 1.0.0.rc1'
|
25
18
|
|
26
|
-
gem.add_development_dependency 'rspec',
|
27
|
-
gem.add_development_dependency 'yard',
|
19
|
+
gem.add_development_dependency 'rspec', '~> 1.3'
|
20
|
+
gem.add_development_dependency 'yard', '~> 0.5'
|
28
21
|
|
29
22
|
end
|
30
23
|
|
31
24
|
Jeweler::GemcutterTasks.new
|
32
25
|
|
26
|
+
FileList['tasks/**/*.rake'].each { |task| import task }
|
27
|
+
|
33
28
|
rescue LoadError
|
34
29
|
puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
|
35
30
|
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0.rc1
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dm-accepts_nested_attributes}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "1.0.0.rc1"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
11
|
-
s.authors = ["Martin Gamsjaeger"]
|
12
|
-
s.date = %q{2010-
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Martin Gamsjaeger (snusnu)"]
|
12
|
+
s.date = %q{2010-05-20}
|
13
13
|
s.description = %q{A datamapper plugin that allows nested model assignment like activerecord.}
|
14
14
|
s.email = %q{gamsnjaga [a] gmail [d] com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -20,16 +20,16 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.files = [
|
21
21
|
".gitignore",
|
22
22
|
"CHANGELOG",
|
23
|
+
"Gemfile",
|
23
24
|
"LICENSE",
|
24
25
|
"README.textile",
|
25
26
|
"Rakefile",
|
26
27
|
"TODO",
|
28
|
+
"VERSION",
|
27
29
|
"dm-accepts_nested_attributes.gemspec",
|
28
30
|
"lib/dm-accepts_nested_attributes.rb",
|
29
|
-
"lib/dm-accepts_nested_attributes/error_collecting.rb",
|
30
31
|
"lib/dm-accepts_nested_attributes/model.rb",
|
31
32
|
"lib/dm-accepts_nested_attributes/resource.rb",
|
32
|
-
"lib/dm-accepts_nested_attributes/transactional_save.rb",
|
33
33
|
"lib/dm-accepts_nested_attributes/version.rb",
|
34
34
|
"spec/accepts_nested_attributes_for_spec.rb",
|
35
35
|
"spec/many_to_many_spec.rb",
|
@@ -45,6 +45,7 @@ Gem::Specification.new do |s|
|
|
45
45
|
"spec/spec_helper.rb",
|
46
46
|
"tasks/changelog.rake",
|
47
47
|
"tasks/ci.rake",
|
48
|
+
"tasks/local_gemfile.rake",
|
48
49
|
"tasks/metrics.rake",
|
49
50
|
"tasks/spec.rake",
|
50
51
|
"tasks/yard.rake",
|
@@ -53,7 +54,7 @@ Gem::Specification.new do |s|
|
|
53
54
|
s.homepage = %q{http://github.com/snusnu/dm-accepts_nested_attributes}
|
54
55
|
s.rdoc_options = ["--charset=UTF-8"]
|
55
56
|
s.require_paths = ["lib"]
|
56
|
-
s.rubygems_version = %q{1.3.
|
57
|
+
s.rubygems_version = %q{1.3.7}
|
57
58
|
s.summary = %q{Nested model assignment for datamapper}
|
58
59
|
s.test_files = [
|
59
60
|
"spec/accepts_nested_attributes_for_spec.rb",
|
@@ -72,19 +73,19 @@ Gem::Specification.new do |s|
|
|
72
73
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
73
74
|
s.specification_version = 3
|
74
75
|
|
75
|
-
if Gem::Version.new(Gem::
|
76
|
-
s.add_runtime_dependency(%q<dm-core>, ["~> 0.
|
77
|
-
s.add_development_dependency(%q<rspec>, ["~> 1.
|
78
|
-
s.add_development_dependency(%q<yard>, ["~> 0.
|
76
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
77
|
+
s.add_runtime_dependency(%q<dm-core>, ["~> 1.0.0.rc1"])
|
78
|
+
s.add_development_dependency(%q<rspec>, ["~> 1.3"])
|
79
|
+
s.add_development_dependency(%q<yard>, ["~> 0.5"])
|
79
80
|
else
|
80
|
-
s.add_dependency(%q<dm-core>, ["~> 0.
|
81
|
-
s.add_dependency(%q<rspec>, ["~> 1.
|
82
|
-
s.add_dependency(%q<yard>, ["~> 0.
|
81
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.0.rc1"])
|
82
|
+
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
83
|
+
s.add_dependency(%q<yard>, ["~> 0.5"])
|
83
84
|
end
|
84
85
|
else
|
85
|
-
s.add_dependency(%q<dm-core>, ["~> 0.
|
86
|
-
s.add_dependency(%q<rspec>, ["~> 1.
|
87
|
-
s.add_dependency(%q<yard>, ["~> 0.
|
86
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.0.rc1"])
|
87
|
+
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
88
|
+
s.add_dependency(%q<yard>, ["~> 0.5"])
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
@@ -56,16 +56,6 @@ module DataMapper
|
|
56
56
|
|
57
57
|
include ::DataMapper::NestedAttributes::Resource
|
58
58
|
|
59
|
-
# TODO i wonder if this is the best place here?
|
60
|
-
# the transactional save behavior is definitely not needed for all resources,
|
61
|
-
# but it's necessary for resources that accept nested attributes
|
62
|
-
# FIXME this leads to weird "no such table" errors when specs are run
|
63
|
-
add_transactional_save_behavior # TODO if repository.adapter.supports_transactions?
|
64
|
-
|
65
|
-
# TODO make this do something
|
66
|
-
# it's only here now to remind me that this is probably the best place to put it
|
67
|
-
add_error_collection_behavior if DataMapper.const_defined?('Validate')
|
68
|
-
|
69
59
|
type = relationship.max > 1 ? :collection : :resource
|
70
60
|
|
71
61
|
define_method "#{association_name}_attributes" do
|
@@ -87,34 +77,6 @@ module DataMapper
|
|
87
77
|
|
88
78
|
private
|
89
79
|
|
90
|
-
##
|
91
|
-
# Provides a hook to include or disable customized transactional save behavior.
|
92
|
-
# Override this method to customize the implementation or disable it altogether.
|
93
|
-
# The current implementation in @see DataMapper::NestedAttributes::TransactionalSave
|
94
|
-
# simply wraps the saving of the complete object tree inside a transaction
|
95
|
-
# and rolls back in case any exceptions are raised, or any of the calls to
|
96
|
-
# @see DataMapper::Resource#save returned false
|
97
|
-
#
|
98
|
-
# @return Not specified
|
99
|
-
#
|
100
|
-
def add_transactional_save_behavior
|
101
|
-
require 'dm-accepts_nested_attributes/transactional_save'
|
102
|
-
include ::DataMapper::NestedAttributes::TransactionalSave
|
103
|
-
end
|
104
|
-
|
105
|
-
##
|
106
|
-
# Provides a hook to include or disable customized error collecting behavior.
|
107
|
-
# Overwrite this method to customize the implementation or disable it altogether.
|
108
|
-
# The current implementation in @see DataMapper::NestedAttributes::ValidationErrorCollecting
|
109
|
-
# simply attaches all errors of related resources to the object that was initially saved.
|
110
|
-
#
|
111
|
-
# @return Not specified
|
112
|
-
#
|
113
|
-
def add_error_collection_behavior
|
114
|
-
require 'dm-accepts_nested_attributes/error_collecting'
|
115
|
-
include ::DataMapper::NestedAttributes::ValidationErrorCollecting
|
116
|
-
end
|
117
|
-
|
118
80
|
##
|
119
81
|
# Checks options passed to @see accepts_nested_attributes_for
|
120
82
|
# If any of the given options is invalid, this method will raise
|
@@ -4,7 +4,7 @@ describe "DataMapper::Model.accepts_nested_attributes_for" do
|
|
4
4
|
|
5
5
|
FIXTURES = <<-RUBY
|
6
6
|
|
7
|
-
class Branch
|
7
|
+
class ::Branch
|
8
8
|
include DataMapper::Resource
|
9
9
|
property :id, Serial
|
10
10
|
has 1, :shop
|
@@ -12,20 +12,20 @@ describe "DataMapper::Model.accepts_nested_attributes_for" do
|
|
12
12
|
has n, :bookings, :through => :items
|
13
13
|
end
|
14
14
|
|
15
|
-
class Shop
|
15
|
+
class ::Shop
|
16
16
|
include DataMapper::Resource
|
17
17
|
property :id, Serial
|
18
18
|
belongs_to :branch
|
19
19
|
end
|
20
20
|
|
21
|
-
class Item
|
21
|
+
class ::Item
|
22
22
|
include DataMapper::Resource
|
23
23
|
property :id, Serial
|
24
24
|
belongs_to :branch
|
25
25
|
has n, :bookings
|
26
26
|
end
|
27
27
|
|
28
|
-
class Booking
|
28
|
+
class ::Booking
|
29
29
|
include DataMapper::Resource
|
30
30
|
property :id, Serial
|
31
31
|
belongs_to :item
|
data/spec/many_to_many_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe "Person.has(n, :projects, :through => :project_memberships);" do
|
|
4
4
|
|
5
5
|
before(:all) do
|
6
6
|
|
7
|
-
class Person
|
7
|
+
class ::Person
|
8
8
|
|
9
9
|
include DataMapper::Resource
|
10
10
|
extend ConstraintSupport
|
@@ -18,7 +18,7 @@ describe "Person.has(n, :projects, :through => :project_memberships);" do
|
|
18
18
|
|
19
19
|
end
|
20
20
|
|
21
|
-
class Project
|
21
|
+
class ::Project
|
22
22
|
|
23
23
|
include DataMapper::Resource
|
24
24
|
extend ConstraintSupport
|
@@ -32,7 +32,7 @@ describe "Person.has(n, :projects, :through => :project_memberships);" do
|
|
32
32
|
|
33
33
|
end
|
34
34
|
|
35
|
-
class ProjectMembership
|
35
|
+
class ::ProjectMembership
|
36
36
|
|
37
37
|
include DataMapper::Resource
|
38
38
|
|
@@ -43,7 +43,7 @@ describe "Person.has(n, :projects, :through => :project_memberships);" do
|
|
43
43
|
|
44
44
|
end
|
45
45
|
|
46
|
-
class Task
|
46
|
+
class ::Task
|
47
47
|
|
48
48
|
include DataMapper::Resource
|
49
49
|
|
@@ -54,7 +54,7 @@ describe "Person.has(n, :projects, :through => :project_memberships);" do
|
|
54
54
|
|
55
55
|
end
|
56
56
|
|
57
|
-
DataMapper.
|
57
|
+
DataMapper.auto_migrate!
|
58
58
|
|
59
59
|
end
|
60
60
|
|
data/spec/many_to_one_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe "Profile.belongs_to(:person);" do
|
|
4
4
|
|
5
5
|
before(:all) do
|
6
6
|
|
7
|
-
class Person
|
7
|
+
class ::Person
|
8
8
|
|
9
9
|
include DataMapper::Resource
|
10
10
|
extend ConstraintSupport
|
@@ -16,7 +16,7 @@ describe "Profile.belongs_to(:person);" do
|
|
16
16
|
|
17
17
|
end
|
18
18
|
|
19
|
-
class Profile
|
19
|
+
class ::Profile
|
20
20
|
|
21
21
|
include DataMapper::Resource
|
22
22
|
|
@@ -28,7 +28,7 @@ describe "Profile.belongs_to(:person);" do
|
|
28
28
|
|
29
29
|
end
|
30
30
|
|
31
|
-
DataMapper.
|
31
|
+
DataMapper.auto_migrate!
|
32
32
|
|
33
33
|
end
|
34
34
|
|
data/spec/one_to_many_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe "Project.has(n, :tasks);" do
|
|
4
4
|
|
5
5
|
before(:all) do
|
6
6
|
|
7
|
-
class Project
|
7
|
+
class ::Project
|
8
8
|
|
9
9
|
include DataMapper::Resource
|
10
10
|
extend ConstraintSupport
|
@@ -16,7 +16,7 @@ describe "Project.has(n, :tasks);" do
|
|
16
16
|
|
17
17
|
end
|
18
18
|
|
19
|
-
class Task
|
19
|
+
class ::Task
|
20
20
|
|
21
21
|
include DataMapper::Resource
|
22
22
|
|
@@ -27,7 +27,7 @@ describe "Project.has(n, :tasks);" do
|
|
27
27
|
|
28
28
|
end
|
29
29
|
|
30
|
-
DataMapper.
|
30
|
+
DataMapper.auto_migrate!
|
31
31
|
|
32
32
|
end
|
33
33
|
|
data/spec/one_to_one_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe "Person.has(1, :profile);" do
|
|
4
4
|
|
5
5
|
before(:all) do
|
6
6
|
|
7
|
-
class Person
|
7
|
+
class ::Person
|
8
8
|
|
9
9
|
include DataMapper::Resource
|
10
10
|
extend ConstraintSupport
|
@@ -17,7 +17,7 @@ describe "Person.has(1, :profile);" do
|
|
17
17
|
|
18
18
|
end
|
19
19
|
|
20
|
-
class Profile
|
20
|
+
class ::Profile
|
21
21
|
|
22
22
|
include DataMapper::Resource
|
23
23
|
|
@@ -29,7 +29,7 @@ describe "Person.has(1, :profile);" do
|
|
29
29
|
|
30
30
|
end
|
31
31
|
|
32
|
-
class Address
|
32
|
+
class ::Address
|
33
33
|
|
34
34
|
include DataMapper::Resource
|
35
35
|
|
@@ -41,7 +41,7 @@ describe "Person.has(1, :profile);" do
|
|
41
41
|
|
42
42
|
end
|
43
43
|
|
44
|
-
DataMapper.
|
44
|
+
DataMapper.auto_migrate!
|
45
45
|
|
46
46
|
end
|
47
47
|
|
@@ -1,26 +1,28 @@
|
|
1
1
|
describe "every accessible many_to_many association", :shared => true do
|
2
2
|
|
3
3
|
it "should allow to update an existing project via Person#projects_attributes" do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
pending_if "#{DataMapper::Spec.adapter_name} doesn't support M2M", !HAS_M2M_SUPPORT do
|
5
|
+
Person.all.size.should == 0
|
6
|
+
Project.all.size.should == 0
|
7
|
+
ProjectMembership.all.size.should == 0
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
person = Person.create :name => 'snusnu'
|
10
|
+
project = Project.create(:name => 'dm-accepts_nested_attributes')
|
11
|
+
project_membership = ProjectMembership.create(:person => person, :project => project)
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
Person.all.size.should == 1
|
14
|
+
Project.all.size.should == 1
|
15
|
+
ProjectMembership.all.size.should == 1
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
person.projects_attributes = [{ :id => project.id, :name => 'still dm-accepts_nested_attributes' }]
|
18
|
+
person.save
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
Person.all.size.should == 1
|
21
|
+
ProjectMembership.all.size.should == 1
|
22
|
+
Project.all.size.should == 1
|
22
23
|
|
23
|
-
|
24
|
+
Project.first.name.should == 'still dm-accepts_nested_attributes'
|
25
|
+
end
|
24
26
|
end
|
25
27
|
|
26
28
|
it "should return the attributes written to Person#projects_attributes from the Person#projects_attributes reader" do
|
@@ -83,26 +85,6 @@ describe "every accessible many_to_many association with no reject_if proc", :sh
|
|
83
85
|
Project.first.name.should == 'dm-accepts_nested_attributes'
|
84
86
|
end
|
85
87
|
|
86
|
-
it "should perform atomic commits" do
|
87
|
-
|
88
|
-
person = Person.new :name => 'snusnu'
|
89
|
-
person.projects_attributes = [{ :name => nil }] # should fail because of validations
|
90
|
-
person.save
|
91
|
-
|
92
|
-
Person.all.size.should == 0 # TODO think more if this should be '1'
|
93
|
-
ProjectMembership.all.size.should == 0
|
94
|
-
Project.all.size.should == 0
|
95
|
-
|
96
|
-
person.name = nil # should fail because of validations
|
97
|
-
person.projects_attributes = [{ :name => nil }]
|
98
|
-
person.save
|
99
|
-
|
100
|
-
Person.all.size.should == 0
|
101
|
-
ProjectMembership.all.size.should == 0
|
102
|
-
Project.all.size.should == 0
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
88
|
end
|
107
89
|
|
108
90
|
describe "every accessible many_to_many association with :allow_destroy => false", :shared => true do
|
@@ -135,28 +117,30 @@ end
|
|
135
117
|
describe "every accessible many_to_many association with :allow_destroy => true", :shared => true do
|
136
118
|
|
137
119
|
it "should allow to delete an existing project via Person#projects_attributes" do
|
138
|
-
|
120
|
+
pending_if "#{DataMapper::Spec.adapter_name} doesn't support M2M", !HAS_M2M_SUPPORT do
|
121
|
+
person = Person.create :name => 'snusnu'
|
139
122
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
123
|
+
project_1 = Project.create(:name => 'dm-accepts_nested_attributes')
|
124
|
+
project_2 = Project.create(:name => 'dm-is-localizable')
|
125
|
+
project_membership_1 = ProjectMembership.create(:person => person, :project => project_1)
|
126
|
+
project_membership_2 = ProjectMembership.create(:person => person, :project => project_2)
|
144
127
|
|
145
|
-
|
146
|
-
|
147
|
-
|
128
|
+
Person.all.size.should == 1
|
129
|
+
ProjectMembership.all.size.should == 2
|
130
|
+
Project.all.size.should == 2
|
148
131
|
|
149
|
-
|
132
|
+
person.projects_attributes = [{ :id => project_1.id, :_delete => true }]
|
150
133
|
|
151
|
-
|
152
|
-
|
153
|
-
|
134
|
+
Person.all.size.should == 1
|
135
|
+
ProjectMembership.all.size.should == 2
|
136
|
+
Project.all.size.should == 2
|
154
137
|
|
155
|
-
|
138
|
+
person.save
|
156
139
|
|
157
|
-
|
158
|
-
|
159
|
-
|
140
|
+
Person.all.size.should == 1
|
141
|
+
ProjectMembership.all.size.should == 1
|
142
|
+
Project.all.size.should == 1
|
143
|
+
end
|
160
144
|
end
|
161
145
|
|
162
146
|
end
|
@@ -21,27 +21,6 @@ describe "every accessible many_to_one association", :shared => true do
|
|
21
21
|
Person.first.name.should == 'Martin Gamsjaeger'
|
22
22
|
end
|
23
23
|
|
24
|
-
it "should perform atomic commits" do
|
25
|
-
Profile.all.size.should == 0
|
26
|
-
Person.all.size.should == 0
|
27
|
-
|
28
|
-
# related resource is invalid
|
29
|
-
profile = Profile.new :nick => 'snusnu'
|
30
|
-
profile.person_attributes = { :name => nil }
|
31
|
-
profile.save.should be_false
|
32
|
-
|
33
|
-
Profile.all.size.should == 0
|
34
|
-
Person.all.size.should == 0
|
35
|
-
|
36
|
-
# self is invalid
|
37
|
-
profile.nick = nil
|
38
|
-
profile.person_attributes = { :name => 'Martin' }
|
39
|
-
profile.save.should be_false
|
40
|
-
|
41
|
-
Profile.all.size.should == 0
|
42
|
-
Person.all.size.should == 0
|
43
|
-
end
|
44
|
-
|
45
24
|
it "should return the attributes written to Profile#person_attributes from the Profile#person_attributes reader" do
|
46
25
|
profile = Profile.new :nick => 'snusnu'
|
47
26
|
profile.person_attributes.should be_nil
|
@@ -63,10 +42,11 @@ describe "every accessible many_to_one association with a valid reject_if proc",
|
|
63
42
|
Profile.all.size.should == 0
|
64
43
|
Person.all.size.should == 0
|
65
44
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
45
|
+
begin
|
46
|
+
profile.save.should be(false)
|
47
|
+
rescue
|
48
|
+
# swallow native FK errors which is basically like expecting save to be false
|
49
|
+
end
|
70
50
|
end
|
71
51
|
|
72
52
|
end
|
@@ -61,27 +61,6 @@ describe "every accessible one_to_many association with no reject_if proc", :sha
|
|
61
61
|
Task.first.name.should == 'write specs'
|
62
62
|
end
|
63
63
|
|
64
|
-
it "should perform atomic commits" do
|
65
|
-
Project.all.size.should == 0
|
66
|
-
Task.all.size.should == 0
|
67
|
-
|
68
|
-
# self is invalid
|
69
|
-
project = Project.new :name => nil
|
70
|
-
project.tasks_attributes = [{ :name => 'write specs' }]
|
71
|
-
project.save.should be_false
|
72
|
-
|
73
|
-
Project.all.size.should == 0
|
74
|
-
Task.all.size.should == 0
|
75
|
-
|
76
|
-
# related resource is invalid
|
77
|
-
project.name = 'dm-accepts_nested_attributes'
|
78
|
-
project.tasks_attributes = [{ :name => nil }] # will fail because of validations
|
79
|
-
project.save
|
80
|
-
|
81
|
-
Project.all.size.should == 0
|
82
|
-
Task.all.size.should == 0
|
83
|
-
end
|
84
|
-
|
85
64
|
end
|
86
65
|
|
87
66
|
describe "every accessible one_to_many association with :allow_destroy => false", :shared => true do
|
@@ -60,25 +60,6 @@ describe "every accessible one_to_one association with no reject_if proc", :shar
|
|
60
60
|
Profile.first.nick.should == 'snusnu'
|
61
61
|
end
|
62
62
|
|
63
|
-
it "should perform atomic commits" do
|
64
|
-
|
65
|
-
# related resource is invalid
|
66
|
-
person = Person.new :name => 'Martin'
|
67
|
-
person.profile_attributes = { :nick => nil } # will fail because of validations
|
68
|
-
person.save.should be_false
|
69
|
-
|
70
|
-
Person.all.size.should == 0
|
71
|
-
Profile.all.size.should == 0
|
72
|
-
|
73
|
-
# self is invalid
|
74
|
-
person.name = nil # will fail because of validations
|
75
|
-
person.profile_attributes = { :nick => 'snusnu' }
|
76
|
-
person.save.should be_false
|
77
|
-
|
78
|
-
Person.all.size.should == 0
|
79
|
-
Profile.all.size.should == 0
|
80
|
-
end
|
81
|
-
|
82
63
|
end
|
83
64
|
|
84
65
|
describe "every accessible one_to_one association with :allow_destroy => false", :shared => true do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,44 +1,16 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require 'spec'
|
1
|
+
require 'dm-core/spec/setup'
|
2
|
+
require 'dm-core/spec/lib/pending_helpers'
|
4
3
|
|
5
|
-
# require the plugin
|
6
4
|
require 'dm-accepts_nested_attributes'
|
7
5
|
|
8
|
-
# allow testing with dm-validations enabled
|
9
|
-
# must be required after the plugin, since
|
10
|
-
# dm-validations seems to need dm-core
|
11
|
-
require 'dm-validations'
|
12
|
-
require 'dm-constraints'
|
13
|
-
|
14
|
-
ENV["SQLITE3_SPEC_URI"] ||= 'sqlite3::memory:'
|
15
|
-
ENV["MYSQL_SPEC_URI"] ||= 'mysql://localhost/dm-accepts_nested_attributes_test'
|
16
|
-
ENV["POSTGRES_SPEC_URI"] ||= 'postgres://postgres@localhost/dm-accepts_nested_attributes_test'
|
17
|
-
|
18
|
-
|
19
|
-
def setup_adapter(name, default_uri = nil)
|
20
|
-
begin
|
21
|
-
DataMapper.setup(name, ENV["#{ENV['ADAPTER'].to_s.upcase}_SPEC_URI"] || default_uri)
|
22
|
-
Object.const_set('ADAPTER', ENV['ADAPTER'].to_sym) if name.to_s == ENV['ADAPTER']
|
23
|
-
true
|
24
|
-
rescue Exception => e
|
25
|
-
if name.to_s == ENV['ADAPTER']
|
26
|
-
Object.const_set('ADAPTER', nil)
|
27
|
-
warn "Could not load do_#{name}: #{e}"
|
28
|
-
end
|
29
|
-
false
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
ENV['ADAPTER'] ||= 'mysql'
|
34
|
-
setup_adapter(:default)
|
35
|
-
|
36
|
-
|
37
6
|
require 'shared/many_to_many_spec'
|
38
7
|
require 'shared/many_to_one_spec'
|
39
8
|
require 'shared/one_to_many_spec'
|
40
9
|
require 'shared/one_to_one_spec'
|
41
10
|
|
11
|
+
DataMapper::Spec.setup
|
12
|
+
|
13
|
+
HAS_M2M_SUPPORT = !%w[in_memory yaml].include?(DataMapper::Spec.adapter_name)
|
42
14
|
|
43
15
|
module ConstraintSupport
|
44
16
|
|
@@ -51,3 +23,15 @@ module ConstraintSupport
|
|
51
23
|
end
|
52
24
|
|
53
25
|
end
|
26
|
+
|
27
|
+
Spec::Runner.configure do |config|
|
28
|
+
|
29
|
+
config.include(DataMapper::Spec::PendingHelpers)
|
30
|
+
|
31
|
+
config.after(:suite) do
|
32
|
+
if DataMapper.respond_to?(:auto_migrate_down!, true)
|
33
|
+
DataMapper.send(:auto_migrate_down!, DataMapper::Spec.adapter.name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
desc "Support bundling from local source code (allows BUNDLE_GEMFILE=Gemfile.local bundle foo)"
|
2
|
+
task :local_gemfile do |t|
|
3
|
+
|
4
|
+
root = Pathname(__FILE__).dirname.parent
|
5
|
+
datamapper = root.parent
|
6
|
+
|
7
|
+
source_regex = /DATAMAPPER = 'git:\/\/github.com\/datamapper'/
|
8
|
+
gem_source_regex = /:git => \"#\{DATAMAPPER\}\/(.+?)(?:\.git)?\"/
|
9
|
+
|
10
|
+
root.join('Gemfile.local').open('w') do |f|
|
11
|
+
root.join('Gemfile').open.each do |line|
|
12
|
+
line.sub!(source_regex, "DATAMAPPER = '#{datamapper}'")
|
13
|
+
line.sub!(gem_source_regex, ':path => "#{DATAMAPPER}/\1"')
|
14
|
+
f.puts line
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/tasks/spec.rake
CHANGED
metadata
CHANGED
@@ -1,47 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-accepts_nested_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 144173629
|
5
|
+
prerelease: true
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
- rc1
|
11
|
+
version: 1.0.0.rc1
|
5
12
|
platform: ruby
|
6
13
|
authors:
|
7
|
-
- Martin Gamsjaeger
|
14
|
+
- Martin Gamsjaeger (snusnu)
|
8
15
|
autorequire:
|
9
16
|
bindir: bin
|
10
17
|
cert_chain: []
|
11
18
|
|
12
|
-
date: 2010-
|
19
|
+
date: 2010-05-20 00:00:00 +02:00
|
13
20
|
default_executable:
|
14
21
|
dependencies:
|
15
22
|
- !ruby/object:Gem::Dependency
|
16
23
|
name: dm-core
|
17
|
-
|
18
|
-
|
19
|
-
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
20
27
|
requirements:
|
21
28
|
- - ~>
|
22
29
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
30
|
+
hash: 144173629
|
31
|
+
segments:
|
32
|
+
- 1
|
33
|
+
- 0
|
34
|
+
- 0
|
35
|
+
- rc1
|
36
|
+
version: 1.0.0.rc1
|
37
|
+
type: :runtime
|
38
|
+
version_requirements: *id001
|
25
39
|
- !ruby/object:Gem::Dependency
|
26
40
|
name: rspec
|
27
|
-
|
28
|
-
|
29
|
-
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
30
44
|
requirements:
|
31
45
|
- - ~>
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
|
34
|
-
|
47
|
+
hash: 9
|
48
|
+
segments:
|
49
|
+
- 1
|
50
|
+
- 3
|
51
|
+
version: "1.3"
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id002
|
35
54
|
- !ruby/object:Gem::Dependency
|
36
55
|
name: yard
|
37
|
-
|
38
|
-
|
39
|
-
|
56
|
+
prerelease: false
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
40
59
|
requirements:
|
41
60
|
- - ~>
|
42
61
|
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
|
62
|
+
hash: 1
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
- 5
|
66
|
+
version: "0.5"
|
67
|
+
type: :development
|
68
|
+
version_requirements: *id003
|
45
69
|
description: A datamapper plugin that allows nested model assignment like activerecord.
|
46
70
|
email: gamsnjaga [a] gmail [d] com
|
47
71
|
executables: []
|
@@ -55,16 +79,16 @@ extra_rdoc_files:
|
|
55
79
|
files:
|
56
80
|
- .gitignore
|
57
81
|
- CHANGELOG
|
82
|
+
- Gemfile
|
58
83
|
- LICENSE
|
59
84
|
- README.textile
|
60
85
|
- Rakefile
|
61
86
|
- TODO
|
87
|
+
- VERSION
|
62
88
|
- dm-accepts_nested_attributes.gemspec
|
63
89
|
- lib/dm-accepts_nested_attributes.rb
|
64
|
-
- lib/dm-accepts_nested_attributes/error_collecting.rb
|
65
90
|
- lib/dm-accepts_nested_attributes/model.rb
|
66
91
|
- lib/dm-accepts_nested_attributes/resource.rb
|
67
|
-
- lib/dm-accepts_nested_attributes/transactional_save.rb
|
68
92
|
- lib/dm-accepts_nested_attributes/version.rb
|
69
93
|
- spec/accepts_nested_attributes_for_spec.rb
|
70
94
|
- spec/many_to_many_spec.rb
|
@@ -80,6 +104,7 @@ files:
|
|
80
104
|
- spec/spec_helper.rb
|
81
105
|
- tasks/changelog.rake
|
82
106
|
- tasks/ci.rake
|
107
|
+
- tasks/local_gemfile.rake
|
83
108
|
- tasks/metrics.rake
|
84
109
|
- tasks/spec.rake
|
85
110
|
- tasks/yard.rake
|
@@ -94,21 +119,29 @@ rdoc_options:
|
|
94
119
|
require_paths:
|
95
120
|
- lib
|
96
121
|
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
97
123
|
requirements:
|
98
124
|
- - ">="
|
99
125
|
- !ruby/object:Gem::Version
|
126
|
+
hash: 3
|
127
|
+
segments:
|
128
|
+
- 0
|
100
129
|
version: "0"
|
101
|
-
version:
|
102
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
103
132
|
requirements:
|
104
|
-
- - "
|
133
|
+
- - ">"
|
105
134
|
- !ruby/object:Gem::Version
|
106
|
-
|
107
|
-
|
135
|
+
hash: 25
|
136
|
+
segments:
|
137
|
+
- 1
|
138
|
+
- 3
|
139
|
+
- 1
|
140
|
+
version: 1.3.1
|
108
141
|
requirements: []
|
109
142
|
|
110
143
|
rubyforge_project:
|
111
|
-
rubygems_version: 1.3.
|
144
|
+
rubygems_version: 1.3.7
|
112
145
|
signing_key:
|
113
146
|
specification_version: 3
|
114
147
|
summary: Nested model assignment for datamapper
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module NestedAttributes
|
3
|
-
|
4
|
-
module ValidationErrorCollecting
|
5
|
-
|
6
|
-
# collect errors on parent associations
|
7
|
-
def before_save_parent_association(association, context)
|
8
|
-
if association.respond_to?(:each)
|
9
|
-
association.each do |r|
|
10
|
-
unless r.valid?(context)
|
11
|
-
r.errors.each { |e| self.errors.add(:general, e) }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
else
|
15
|
-
unless association.valid?(context)
|
16
|
-
association.errors.each { |e| self.errors.add(:general, e) }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# collect errors on child associations
|
22
|
-
def before_save_child_association(association, context)
|
23
|
-
if association.respond_to?(:valid?)
|
24
|
-
unless association.valid?(context)
|
25
|
-
association.errors.each { |e| self.errors.add(:general, e) }
|
26
|
-
end
|
27
|
-
else
|
28
|
-
self.errors.add(:general, "child association is missing")
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module NestedAttributes
|
3
|
-
|
4
|
-
module TransactionalSave
|
5
|
-
|
6
|
-
##
|
7
|
-
# Overrides @see DataMapper::Resource#save to perform inside a transaction.
|
8
|
-
# The current implementation simply wraps the saving of the complete object tree
|
9
|
-
# inside a transaction and rolls back in case any exceptions are raised,
|
10
|
-
# or any of the calls to
|
11
|
-
#
|
12
|
-
# @see DataMapper::Resource#save
|
13
|
-
#
|
14
|
-
# @return [Boolean]
|
15
|
-
# true if all related resources were saved properly
|
16
|
-
#
|
17
|
-
def save
|
18
|
-
transaction { |t| super || t.rollback && false }
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|