dm-rails 1.0.4 → 1.1.0.rc1
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.
- data/Gemfile +45 -19
- data/LICENSE +1 -1
- data/README.rdoc +9 -14
- data/Rakefile +3 -8
- data/VERSION +1 -1
- data/dm-rails.gemspec +76 -56
- data/lib/dm-rails/mass_assignment_security.rb +42 -18
- data/lib/dm-rails/multiparameter_attributes.rb +167 -0
- data/lib/dm-rails/railtie.rb +4 -1
- data/lib/dm-rails/session_store.rb +4 -0
- data/spec/models/fake.rb +31 -0
- data/spec/models/topic.rb +11 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/unit/mass_assignment_security_spec.rb +43 -0
- data/spec/unit/multiparameter_attributes_spec.rb +167 -0
- metadata +80 -65
- data/.gitignore +0 -37
- data/tasks/ci.rake +0 -1
- data/tasks/local_gemfile.rake +0 -16
- data/tasks/metrics.rake +0 -37
data/Gemfile
CHANGED
@@ -1,37 +1,63 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
1
3
|
source 'http://rubygems.org'
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
+
SOURCE = ENV.fetch('SOURCE', :git).to_sym
|
6
|
+
REPO_POSTFIX = SOURCE == :path ? '' : '.git'
|
7
|
+
DATAMAPPER = SOURCE == :path ? Pathname(__FILE__).dirname.parent : 'http://github.com/datamapper'
|
8
|
+
DM_VERSION = '~> 1.0.2'
|
5
9
|
|
6
10
|
group :runtime do
|
7
11
|
|
8
|
-
|
12
|
+
gem 'actionpack', '~> 3.0.4', :require => 'action_pack'
|
13
|
+
gem 'activesupport', '~> 3.0.4', :require => 'active_support'
|
14
|
+
gem 'dm-core', DM_VERSION, SOURCE => "#{DATAMAPPER}/dm-core#{REPO_POSTFIX}"
|
15
|
+
gem 'dm-active_model', DM_VERSION, SOURCE => "#{DATAMAPPER}/dm-active_model#{REPO_POSTFIX}"
|
16
|
+
gem 'i18n', '~> 0.5.0'
|
17
|
+
gem 'railties', '~> 3.0.4', :require => 'rails'
|
9
18
|
|
10
|
-
|
11
|
-
gem 'actionpack', :require => 'action_pack'
|
12
|
-
gem 'railties', :require => 'rails'
|
19
|
+
end
|
13
20
|
|
14
|
-
|
21
|
+
group :development do
|
15
22
|
|
16
|
-
gem '
|
17
|
-
gem '
|
23
|
+
gem 'jeweler', '~> 1.5.2'
|
24
|
+
gem 'rake', '~> 0.8.7'
|
25
|
+
gem 'rspec', '~> 1.3.1'
|
18
26
|
|
19
27
|
end
|
20
28
|
|
21
|
-
group :
|
29
|
+
group :quality do
|
22
30
|
|
23
|
-
gem '
|
24
|
-
gem '
|
31
|
+
gem 'rcov', '~> 0.9.9', :platforms => :mri_18
|
32
|
+
gem 'yard', '~> 0.6'
|
33
|
+
gem 'yardstick', '~> 0.2'
|
25
34
|
|
26
35
|
end
|
27
36
|
|
28
|
-
group :
|
37
|
+
group :datamapper do
|
38
|
+
adapters = ENV['ADAPTER'] || ENV['ADAPTERS']
|
39
|
+
adapters = adapters.to_s.tr(',', ' ').split.uniq - %w[ in_memory ]
|
40
|
+
|
41
|
+
DO_VERSION = '~> 0.10.2'
|
42
|
+
DM_DO_ADAPTERS = %w[ sqlite postgres mysql oracle sqlserver ]
|
29
43
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
gem 'roodi', '~> 2.1'
|
34
|
-
gem 'yard', '~> 0.5'
|
35
|
-
gem 'yardstick', '~> 0.1'
|
44
|
+
if (do_adapters = DM_DO_ADAPTERS & adapters).any?
|
45
|
+
options = {}
|
46
|
+
options[:git] = "#{DATAMAPPER}/do#{REPO_POSTFIX}" if ENV['DO_GIT'] == 'true'
|
36
47
|
|
48
|
+
gem 'data_objects', DO_VERSION, options.dup
|
49
|
+
|
50
|
+
do_adapters.each do |adapter|
|
51
|
+
adapter = 'sqlite3' if adapter == 'sqlite'
|
52
|
+
gem "do_#{adapter}", DO_VERSION, options.dup
|
53
|
+
end
|
54
|
+
|
55
|
+
gem 'dm-do-adapter', DM_VERSION, SOURCE => "#{DATAMAPPER}/dm-do-adapter#{REPO_POSTFIX}"
|
56
|
+
end
|
57
|
+
|
58
|
+
gem 'dm-migrations', DM_VERSION, SOURCE => "#{DATAMAPPER}/dm-migrations#{REPO_POSTFIX}"
|
59
|
+
|
60
|
+
adapters.each do |adapter|
|
61
|
+
gem "dm-#{adapter}-adapter", DM_VERSION, SOURCE => "#{DATAMAPPER}/dm-#{adapter}-adapter#{REPO_POSTFIX}"
|
62
|
+
end
|
37
63
|
end
|
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= dm-rails
|
2
2
|
|
3
|
-
This gem provides the railtie that allows {datamapper}[http://github.com/datamapper/dm-core] to hook into {rails3}[http://github.com/rails/rails] and thus behave like a rails framework component. Just like
|
3
|
+
This gem provides the railtie that allows {datamapper}[http://github.com/datamapper/dm-core] to hook into {rails3}[http://github.com/rails/rails] and thus behave like a rails framework component. Just like activerecord does in rails, {dm-rails}[http://github.com/datamapper/dm-rails] uses the railtie API to hook into rails. The two are actually hooked into rails almost identically.
|
4
4
|
|
5
5
|
Creating new datamapper apps on rails3 from scratch is actually really easy. The following will guide you through the process.
|
6
6
|
|
@@ -37,6 +37,7 @@ gives us. First you need to uncomment/remove a seemingly invalid rspec configura
|
|
37
37
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
38
38
|
|
39
39
|
RSpec.configure do |config|
|
40
|
+
|
40
41
|
# == Mock Framework
|
41
42
|
#
|
42
43
|
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
@@ -46,15 +47,8 @@ gives us. First you need to uncomment/remove a seemingly invalid rspec configura
|
|
46
47
|
# config.mock_with :rr
|
47
48
|
config.mock_with :rspec
|
48
49
|
|
49
|
-
config.before(:
|
50
|
-
|
51
|
-
# I can't find that option when looking at current rspec-core source
|
52
|
-
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
50
|
+
config.before(:suite) { DataMapper.auto_migrate! }
|
53
51
|
|
54
|
-
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
55
|
-
# examples within a transaction, comment the following line or assign false
|
56
|
-
# instead of true.
|
57
|
-
# config.use_transactional_fixtures = true
|
58
52
|
end
|
59
53
|
|
60
54
|
With this in place, running
|
@@ -105,7 +99,7 @@ Using {bundler}[http://github.com/carlhuda/bundler] it's really easy to get an a
|
|
105
99
|
gem 'actionmailer', RAILS_VERSION, :require => 'action_mailer'
|
106
100
|
gem 'railties', RAILS_VERSION, :require => 'rails'
|
107
101
|
|
108
|
-
gem 'dm-rails', '~> 1.0.
|
102
|
+
gem 'dm-rails', '~> 1.1.0.rc1'
|
109
103
|
gem 'dm-sqlite-adapter', DM_VERSION
|
110
104
|
|
111
105
|
# You can use any of the other available database adapters.
|
@@ -542,11 +536,12 @@ Currently dm-rails publishes the same benchmarking information like active_recor
|
|
542
536
|
Completed in 9ms (Views: 7.6ms | Models: 0.6ms) with 200
|
543
537
|
|
544
538
|
|
545
|
-
==
|
539
|
+
== Migrations
|
546
540
|
|
547
|
-
|
548
|
-
|
541
|
+
The latest released version of {dm-migrations}[http://github.com/datamapper/dm-migrations] suffers from a {bug}[http://datamapper.lighthouseapp.com/projects/20609/tickets/1214]
|
542
|
+
that prevents any migration to be run at all when invoked via the standard `rake db:migrate` command. Currently, there are two ways to workaround that.
|
549
543
|
|
544
|
+
You can either point {dm-migrations}[http://github.com/datamapper/dm-migrations] to :git in your application's Gemfile, or you can patch the generated Rakefile as shown at the bottom of the related {bug report}[http://datamapper.lighthouseapp.com/projects/20609/tickets/1214].
|
550
545
|
|
551
546
|
== TODO (not necessarily in that order)
|
552
547
|
|
@@ -589,4 +584,4 @@ Thx to all contributors, every patch, big or small is very much appreciated!
|
|
589
584
|
|
590
585
|
== Copyright
|
591
586
|
|
592
|
-
Copyright (c)
|
587
|
+
Copyright (c) 2011-2010 The dm-rails team. See {LICENSE}[http://github.com/datamapper/dm-rails/blob/master/LICENSE] for details.
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
|
4
4
|
begin
|
5
|
-
gem 'jeweler', '~> 1.
|
5
|
+
gem 'jeweler', '~> 1.5.2'
|
6
6
|
require 'jeweler'
|
7
7
|
|
8
8
|
Jeweler::Tasks.new do |gem|
|
@@ -14,12 +14,6 @@ begin
|
|
14
14
|
gem.authors = [ 'Martin Gamsjaeger (snusnu)', 'Dan Kubb' ]
|
15
15
|
|
16
16
|
gem.rubyforge_project = 'datamapper'
|
17
|
-
|
18
|
-
gem.add_dependency 'dm-core', '~> 1.0.0'
|
19
|
-
gem.add_dependency 'dm-active_model', '~> 1.0.3'
|
20
|
-
gem.add_dependency 'activesupport', '~> 3.0.0'
|
21
|
-
gem.add_dependency 'actionpack', '~> 3.0.0'
|
22
|
-
gem.add_dependency 'railties', '~> 3.0.0'
|
23
17
|
end
|
24
18
|
|
25
19
|
Jeweler::GemcutterTasks.new
|
@@ -29,4 +23,5 @@ rescue LoadError
|
|
29
23
|
puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
|
30
24
|
end
|
31
25
|
|
32
|
-
|
26
|
+
require "spec/rake/spectask"
|
27
|
+
Spec::Rake::SpecTask.new
|
data/VERSION
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
1.0.
|
1
|
+
1.1.0.rc1
|
2
2
|
|
data/dm-rails.gemspec
CHANGED
@@ -1,87 +1,107 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dm-rails}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.1.0.rc1"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Martin Gamsjaeger (snusnu)", "Dan Kubb"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-02-28}
|
13
13
|
s.description = %q{Integrate DataMapper with Rails 3}
|
14
14
|
s.email = %q{gamsnjaga@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
|
17
|
+
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
21
|
+
"Gemfile",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"dm-rails.gemspec",
|
27
|
+
"lib/dm-rails.rb",
|
28
|
+
"lib/dm-rails/configuration.rb",
|
29
|
+
"lib/dm-rails/mass_assignment_security.rb",
|
30
|
+
"lib/dm-rails/middleware/identity_map.rb",
|
31
|
+
"lib/dm-rails/multiparameter_attributes.rb",
|
32
|
+
"lib/dm-rails/railtie.rb",
|
33
|
+
"lib/dm-rails/railties/controller_runtime.rb",
|
34
|
+
"lib/dm-rails/railties/database.rake",
|
35
|
+
"lib/dm-rails/railties/i18n_support.rb",
|
36
|
+
"lib/dm-rails/railties/log_listener.rb",
|
37
|
+
"lib/dm-rails/railties/log_subscriber.rb",
|
38
|
+
"lib/dm-rails/session_store.rb",
|
39
|
+
"lib/dm-rails/setup.rb",
|
40
|
+
"lib/dm-rails/storage.rb",
|
41
|
+
"lib/generators/data_mapper.rb",
|
42
|
+
"lib/generators/data_mapper/migration/migration_generator.rb",
|
43
|
+
"lib/generators/data_mapper/migration/templates/migration.rb",
|
44
|
+
"lib/generators/data_mapper/model/model_generator.rb",
|
45
|
+
"lib/generators/data_mapper/model/templates/model.rb",
|
46
|
+
"lib/generators/data_mapper/observer/observer_generator.rb",
|
47
|
+
"lib/generators/data_mapper/observer/templates/observer.rb",
|
48
|
+
"spec/models/fake.rb",
|
49
|
+
"spec/models/topic.rb",
|
50
|
+
"spec/spec.opts",
|
51
|
+
"spec/spec_helper.rb",
|
52
|
+
"spec/unit/mass_assignment_security_spec.rb",
|
53
|
+
"spec/unit/multiparameter_attributes_spec.rb",
|
54
|
+
"tasks/clean.rake",
|
55
|
+
"tasks/yard.rake",
|
56
|
+
"tasks/yardstick.rake"
|
54
57
|
]
|
55
58
|
s.homepage = %q{http://github.com/datamapper/dm-rails}
|
56
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
57
59
|
s.require_paths = ["lib"]
|
58
60
|
s.rubyforge_project = %q{datamapper}
|
59
|
-
s.rubygems_version = %q{1.
|
61
|
+
s.rubygems_version = %q{1.5.2}
|
60
62
|
s.summary = %q{Use DataMapper with Rails 3}
|
63
|
+
s.test_files = [
|
64
|
+
"spec/models/fake.rb",
|
65
|
+
"spec/models/topic.rb",
|
66
|
+
"spec/spec_helper.rb",
|
67
|
+
"spec/unit/mass_assignment_security_spec.rb",
|
68
|
+
"spec/unit/multiparameter_attributes_spec.rb"
|
69
|
+
]
|
61
70
|
|
62
71
|
if s.respond_to? :specification_version then
|
63
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
64
72
|
s.specification_version = 3
|
65
73
|
|
66
74
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
67
|
-
s.add_runtime_dependency(%q<
|
68
|
-
s.add_runtime_dependency(%q<
|
69
|
-
s.add_runtime_dependency(%q<
|
70
|
-
s.add_runtime_dependency(%q<
|
71
|
-
s.add_runtime_dependency(%q<
|
75
|
+
s.add_runtime_dependency(%q<actionpack>, ["~> 3.0.4"])
|
76
|
+
s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.4"])
|
77
|
+
s.add_runtime_dependency(%q<dm-core>, ["~> 1.0.2"])
|
78
|
+
s.add_runtime_dependency(%q<dm-active_model>, ["~> 1.0.2"])
|
79
|
+
s.add_runtime_dependency(%q<i18n>, ["~> 0.5.0"])
|
80
|
+
s.add_runtime_dependency(%q<railties>, ["~> 3.0.4"])
|
81
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
82
|
+
s.add_development_dependency(%q<rake>, ["~> 0.8.7"])
|
83
|
+
s.add_development_dependency(%q<rspec>, ["~> 1.3.1"])
|
72
84
|
else
|
73
|
-
s.add_dependency(%q<
|
74
|
-
s.add_dependency(%q<
|
75
|
-
s.add_dependency(%q<
|
76
|
-
s.add_dependency(%q<
|
77
|
-
s.add_dependency(%q<
|
85
|
+
s.add_dependency(%q<actionpack>, ["~> 3.0.4"])
|
86
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.4"])
|
87
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.2"])
|
88
|
+
s.add_dependency(%q<dm-active_model>, ["~> 1.0.2"])
|
89
|
+
s.add_dependency(%q<i18n>, ["~> 0.5.0"])
|
90
|
+
s.add_dependency(%q<railties>, ["~> 3.0.4"])
|
91
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
92
|
+
s.add_dependency(%q<rake>, ["~> 0.8.7"])
|
93
|
+
s.add_dependency(%q<rspec>, ["~> 1.3.1"])
|
78
94
|
end
|
79
95
|
else
|
80
|
-
s.add_dependency(%q<
|
81
|
-
s.add_dependency(%q<
|
82
|
-
s.add_dependency(%q<
|
83
|
-
s.add_dependency(%q<
|
84
|
-
s.add_dependency(%q<
|
96
|
+
s.add_dependency(%q<actionpack>, ["~> 3.0.4"])
|
97
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.4"])
|
98
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.2"])
|
99
|
+
s.add_dependency(%q<dm-active_model>, ["~> 1.0.2"])
|
100
|
+
s.add_dependency(%q<i18n>, ["~> 0.5.0"])
|
101
|
+
s.add_dependency(%q<railties>, ["~> 3.0.4"])
|
102
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
103
|
+
s.add_dependency(%q<rake>, ["~> 0.8.7"])
|
104
|
+
s.add_dependency(%q<rspec>, ["~> 1.3.1"])
|
85
105
|
end
|
86
106
|
end
|
87
107
|
|
@@ -5,9 +5,16 @@ require 'active_model'
|
|
5
5
|
|
6
6
|
module ActiveModel
|
7
7
|
module MassAssignmentSecurity
|
8
|
+
# Provides a patched version of the Sanitizer used in Rails to handle property
|
9
|
+
# and relationship objects as keys. There is no way to inject a custom sanitizer
|
10
|
+
# without reimplementing the permission sets.
|
8
11
|
module Sanitizer
|
9
|
-
# Returns all attributes not denied by the authorizer.
|
10
|
-
#
|
12
|
+
# Returns all attributes not denied by the authorizer.
|
13
|
+
#
|
14
|
+
# @param [Hash{Symbol,String,::DataMapper::Property,::DataMapper::Relationship=>Object}] attributes
|
15
|
+
# Names and values of attributes to sanitize.
|
16
|
+
# @return [Hash]
|
17
|
+
# Sanitized hash of attributes.
|
11
18
|
def sanitize(attributes)
|
12
19
|
sanitized_attributes = attributes.reject do |key, value|
|
13
20
|
key_name = key.name rescue key
|
@@ -21,7 +28,11 @@ module ActiveModel
|
|
21
28
|
end
|
22
29
|
|
23
30
|
module DataMapper
|
24
|
-
#
|
31
|
+
# Include this module into a DataMapper model to enable ActiveModel's mass
|
32
|
+
# assignment security.
|
33
|
+
#
|
34
|
+
# To use second parameter of {#attributes=} make sure to include this module
|
35
|
+
# last.
|
25
36
|
module MassAssignmentSecurity
|
26
37
|
extend ::ActiveSupport::Concern
|
27
38
|
include ::ActiveModel::MassAssignmentSecurity
|
@@ -32,34 +43,47 @@ module DataMapper
|
|
32
43
|
def logger
|
33
44
|
@logger ||= ::DataMapper.logger
|
34
45
|
end
|
35
|
-
|
36
46
|
end
|
37
47
|
|
38
|
-
#
|
39
|
-
#
|
48
|
+
# Sanitizes the specified +attributes+ according to the defined mass-assignment
|
49
|
+
# security rules and calls +super+ with the result.
|
50
|
+
#
|
51
|
+
# Use either +attr_accessible+ to specify which attributes are allowed to be
|
52
|
+
# assigned via {#attributes=}, or +attr_protected+ to specify which attributes
|
53
|
+
# are *not* allowed to be assigned via {#attributes=}.
|
54
|
+
#
|
55
|
+
# +attr_accessible+ and +attr_protected+ are mutually exclusive.
|
56
|
+
#
|
57
|
+
# @param [Hash{Symbol,String,::DataMapper::Property,::DataMapper::Relationship=>Object}] attributes
|
58
|
+
# Names and values of attributes to sanitize.
|
59
|
+
# @param [Boolean] guard_protected_attributes
|
60
|
+
# Determines whether mass-security rules are applied (when +true+) or not.
|
61
|
+
# @return [Hash]
|
62
|
+
# Sanitized hash of attributes.
|
63
|
+
# @api public
|
40
64
|
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
# attributes not included in that won't be allowed to be mass-assigned.
|
65
|
+
# @example [Usage]
|
66
|
+
# class User
|
67
|
+
# include DataMapper::Resource
|
68
|
+
# include DataMapper::MassAssignmentSecurity
|
46
69
|
#
|
47
|
-
#
|
48
|
-
#
|
70
|
+
# property :name, String
|
71
|
+
# property :is_admin, Boolean
|
72
|
+
#
|
73
|
+
# # Only allow name to be set via #attributes=
|
74
|
+
# attr_accessible :name
|
49
75
|
# end
|
50
76
|
#
|
51
77
|
# user = User.new
|
52
78
|
# user.attributes = { :username => 'Phusion', :is_admin => true }
|
53
|
-
# user.username
|
54
|
-
# user.is_admin
|
79
|
+
# user.username # => "Phusion"
|
80
|
+
# user.is_admin # => false
|
55
81
|
#
|
56
82
|
# user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false)
|
57
|
-
# user.is_admin
|
83
|
+
# user.is_admin # => true
|
58
84
|
def attributes=(attributes, guard_protected_attributes = true)
|
59
85
|
attributes = sanitize_for_mass_assignment(attributes) if guard_protected_attributes
|
60
86
|
super(attributes)
|
61
87
|
end
|
62
|
-
|
63
88
|
end
|
64
89
|
end
|
65
|
-
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'active_support/core_ext/module/aliasing'
|
2
|
+
|
3
|
+
module Rails
|
4
|
+
module DataMapper
|
5
|
+
# Encapsulates an error of a multiparameter assignment.
|
6
|
+
class MultiparameterAssignmentError < StandardError
|
7
|
+
# Gets the target attribute of the assignment.
|
8
|
+
# @return [String]
|
9
|
+
attr_reader :attribute
|
10
|
+
|
11
|
+
# Gets the assigned values.
|
12
|
+
# @return [Array]
|
13
|
+
attr_reader :values
|
14
|
+
|
15
|
+
# Gets the exception raised on the assignment.
|
16
|
+
# @return [Exception]
|
17
|
+
attr_reader :exception
|
18
|
+
|
19
|
+
# Initializes a new instance of the {MultiparameterAssignmentError} class.
|
20
|
+
#
|
21
|
+
# @param [String] attribute The target attribute of the assignment.
|
22
|
+
# @param [Array] values The assigned values.
|
23
|
+
# @param [Exception] exception The exception raised on the assignment.
|
24
|
+
def initialize(attribute, values, exception)
|
25
|
+
super("Could not assign #{values.inspect} to #{attribute} (#{exception.message}).")
|
26
|
+
@attribute = attribute
|
27
|
+
@values = values
|
28
|
+
@exception = exception
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Raised by {MultiparameterAttributes#attributes=} when there are errors when
|
33
|
+
# merging multiparameter attributes. Use {#errors} to get the array of errors
|
34
|
+
# occured.
|
35
|
+
class MultiparameterAssignmentErrors < StandardError
|
36
|
+
# Gets the array of assignment errors.
|
37
|
+
# @return [Array<MultiparameterAssignmentError>]
|
38
|
+
attr_reader :errors
|
39
|
+
|
40
|
+
# Initializes a new instance of the {MultiparameterAssignmentErrors} class.
|
41
|
+
#
|
42
|
+
# @param [Array<MultiparameterAssignmentError>] errors
|
43
|
+
# The array of assignment errors.
|
44
|
+
# @param [String] message Optional error message.
|
45
|
+
def initialize(errors, message = nil)
|
46
|
+
super(message || "#{errors.size} error#{errors.size == 1 ? '' : 's'} on assignment of multiparameter attributes.")
|
47
|
+
@errors = errors
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Include this module into a DataMapper model to enable multiparameter
|
52
|
+
# attributes.
|
53
|
+
#
|
54
|
+
# A multiparameter attribute has +attr(Xc)+ as name where +attr+ specifies
|
55
|
+
# the attribute, +X+ the position of the value, and +c+ an optional typecast
|
56
|
+
# identifier. All values that share an +attr+ are sorted by their position,
|
57
|
+
# optionally cast using +#to_c+ (where +c+ is the typecast identifier) and
|
58
|
+
# then used to instantiate the proper attribute value.
|
59
|
+
#
|
60
|
+
# @example
|
61
|
+
# # Assigning a hash with multiparameter values for a +Date+ property called
|
62
|
+
# # +written_on+:
|
63
|
+
# resource.attributes = {
|
64
|
+
# 'written_on(1i)' => '2004',
|
65
|
+
# 'written_on(2i)' => '6',
|
66
|
+
# 'written_on(3i)' => '24' }
|
67
|
+
#
|
68
|
+
# # +Date+ will be initialized with each string cast to a number using
|
69
|
+
# # #to_i.
|
70
|
+
# resource.written_on == Date.new(2004, 6, 24)
|
71
|
+
module MultiparameterAttributes
|
72
|
+
# Merges multiparameter attributes and calls +super+ with the merged
|
73
|
+
# attributes.
|
74
|
+
#
|
75
|
+
# @param [Hash{String,Symbol=>Object}] attributes
|
76
|
+
# Names and values of attributes to assign.
|
77
|
+
# @return [Hash]
|
78
|
+
# Names and values of attributes assigned.
|
79
|
+
# @raise [MultiparameterAssignmentErrors]
|
80
|
+
# One or more multiparameters could not be assigned.
|
81
|
+
# @api public
|
82
|
+
def attributes=(attributes)
|
83
|
+
attribs = attributes.dup
|
84
|
+
multi_parameter_attributes = []
|
85
|
+
attribs.each do |k, v|
|
86
|
+
if k.to_s.include?("(")
|
87
|
+
multi_parameter_attributes << [ k, v ]
|
88
|
+
attribs.delete(k)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
attribs.merge!(merge_multiparameter_attributes(multi_parameter_attributes))
|
93
|
+
super(attribs)
|
94
|
+
end
|
95
|
+
|
96
|
+
protected
|
97
|
+
def merge_multiparameter_attributes(pairs)
|
98
|
+
pairs = extract_multiparameter_attributes(pairs)
|
99
|
+
|
100
|
+
errors = []
|
101
|
+
attributes = {}
|
102
|
+
pairs.each do |name, values_with_empty_parameters|
|
103
|
+
# ActiveRecord keeps the empty values to set dates without a year.
|
104
|
+
# Removing all nils (instead of removing only trailing nils) seems
|
105
|
+
# like a weird behavior though.
|
106
|
+
values = values_with_empty_parameters.compact
|
107
|
+
|
108
|
+
if values.empty?
|
109
|
+
attributes[name] = nil
|
110
|
+
next
|
111
|
+
end
|
112
|
+
|
113
|
+
klass = properties[name].primitive
|
114
|
+
begin
|
115
|
+
attributes[name] =
|
116
|
+
if klass == Time
|
117
|
+
Time.local(*values)
|
118
|
+
elsif klass == Date
|
119
|
+
# Date does not replace nil values with defaults.
|
120
|
+
Date.new(*values_with_empty_parameters.map { |v| v.nil? ? 1 : v })
|
121
|
+
else
|
122
|
+
klass.new(*values)
|
123
|
+
end
|
124
|
+
rescue => ex
|
125
|
+
errors << MultiparameterAssignmentError.new(name, values, ex)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
unless errors.empty?
|
130
|
+
raise MultiparameterAssignmentErrors.new(errors)
|
131
|
+
end
|
132
|
+
|
133
|
+
attributes
|
134
|
+
end
|
135
|
+
|
136
|
+
def extract_multiparameter_attributes(pairs)
|
137
|
+
attributes = {}
|
138
|
+
|
139
|
+
for multiparameter_name, value in pairs
|
140
|
+
unless multiparameter_name =~ /\A ([^\)]+) \( ([0-9]+) ([a-z])? \) \z/x
|
141
|
+
raise "Invalid multiparameter name #{multiparameter_name.inspect}."
|
142
|
+
end
|
143
|
+
|
144
|
+
name, position, typecast = $1, $2, $3
|
145
|
+
attributes[name] ||= []
|
146
|
+
|
147
|
+
parameter_value =
|
148
|
+
if value.empty?
|
149
|
+
nil
|
150
|
+
elsif typecast
|
151
|
+
value.send('to_' + typecast)
|
152
|
+
else
|
153
|
+
value
|
154
|
+
end
|
155
|
+
|
156
|
+
attributes[name] << [ position, parameter_value ]
|
157
|
+
end
|
158
|
+
|
159
|
+
# Order each parameter array according to the position, then discard the
|
160
|
+
# position.
|
161
|
+
attributes.each { |name, values|
|
162
|
+
attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last }
|
163
|
+
}
|
164
|
+
end
|
165
|
+
end # MultiparameterAttributes
|
166
|
+
end
|
167
|
+
end
|
data/lib/dm-rails/railtie.rb
CHANGED
@@ -20,6 +20,7 @@ require "dm-rails/railties/i18n_support"
|
|
20
20
|
# but users will still need to include it into the
|
21
21
|
# models they want it to use it in.
|
22
22
|
require 'dm-rails/mass_assignment_security'
|
23
|
+
require 'dm-rails/multiparameter_attributes'
|
23
24
|
|
24
25
|
module Rails
|
25
26
|
module DataMapper
|
@@ -39,7 +40,8 @@ module Rails
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def setup_i18n_support(app)
|
42
|
-
::DataMapper::Model.
|
43
|
+
::DataMapper::Model.append_extensions(::ActiveModel::Translation)
|
44
|
+
::DataMapper::Model.append_extensions(Rails::DataMapper::I18nSupport)
|
43
45
|
end
|
44
46
|
|
45
47
|
def setup_controller_runtime(app)
|
@@ -56,6 +58,7 @@ module Rails
|
|
56
58
|
|
57
59
|
initializer 'data_mapper.configuration' do |app|
|
58
60
|
configure_data_mapper(app)
|
61
|
+
::DataMapper::Model.append_inclusions(Rails::DataMapper::MultiparameterAttributes)
|
59
62
|
end
|
60
63
|
|
61
64
|
initializer 'data_mapper.logger' do |app|
|
data/spec/models/fake.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rails; module DataMapper; module Models
|
2
|
+
class Composite
|
3
|
+
attr_accessor :args
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
@args = args
|
7
|
+
end
|
8
|
+
|
9
|
+
def ==(other)
|
10
|
+
eql?(other)
|
11
|
+
end
|
12
|
+
|
13
|
+
def eql?(other)
|
14
|
+
!other.nil? && other.args == args
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Fake
|
19
|
+
super_module = Module.new do
|
20
|
+
def _super_attributes=(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def attributes=(*args)
|
24
|
+
self.send(:_super_attributes=, *args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
include super_module
|
28
|
+
|
29
|
+
include ::Rails::DataMapper::MultiparameterAttributes
|
30
|
+
end
|
31
|
+
end; end; end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Rails; module DataMapper; module Models
|
2
|
+
class Topic
|
3
|
+
include ::DataMapper::Resource
|
4
|
+
include ::Rails::DataMapper::MultiparameterAttributes
|
5
|
+
|
6
|
+
property :id, Serial
|
7
|
+
property :last_read, Date
|
8
|
+
property :written_on, Time
|
9
|
+
property :updated_at, DateTime
|
10
|
+
end
|
11
|
+
end; end; end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift File.expand_path File.dirname(__FILE__) + '../lib'
|
2
|
+
require 'dm-core/spec/setup'
|
3
|
+
require 'dm-core/spec/lib/adapter_helpers'
|
4
|
+
require 'dm-core/spec/lib/spec_helper'
|
5
|
+
require 'dm-core/spec/lib/pending_helpers'
|
6
|
+
|
7
|
+
DataMapper::Spec.setup
|
8
|
+
DataMapper.finalize
|
9
|
+
|
10
|
+
Spec::Runner.configure do |config|
|
11
|
+
|
12
|
+
config.extend(DataMapper::Spec::Adapters::Helpers)
|
13
|
+
config.include(DataMapper::Spec::PendingHelpers)
|
14
|
+
|
15
|
+
config.after :all do
|
16
|
+
DataMapper::Spec.cleanup_models
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm-rails/mass_assignment_security'
|
3
|
+
|
4
|
+
# Because mass-assignment security is based on ActiveModel we just have to
|
5
|
+
# ensure that ActiveModel is called.
|
6
|
+
describe DataMapper::MassAssignmentSecurity do
|
7
|
+
before :all do
|
8
|
+
class Fake
|
9
|
+
super_module = Module.new do
|
10
|
+
def _super_attributes=(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def attributes=(*args)
|
14
|
+
self.send(:_super_attributes=, *args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
include super_module
|
18
|
+
|
19
|
+
include ::DataMapper::MassAssignmentSecurity
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#attributes=' do
|
24
|
+
it 'calls super with sanitized attributes' do
|
25
|
+
attributes = { :name => 'John', :is_admin => true }
|
26
|
+
sanitized_attributes = { :name => 'John' }
|
27
|
+
model = Fake.new
|
28
|
+
model.should_receive(:sanitize_for_mass_assignment).with(attributes).and_return(sanitized_attributes)
|
29
|
+
model.should_receive(:_super_attributes=).with(sanitized_attributes)
|
30
|
+
|
31
|
+
model.attributes = attributes
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'skips sanitation when called with true' do
|
35
|
+
attributes = { :name => 'John', :is_admin => true }
|
36
|
+
sanitized_attributes = { :name => 'John' }
|
37
|
+
model = Fake.new
|
38
|
+
model.should_receive(:_super_attributes=).with(attributes)
|
39
|
+
|
40
|
+
model.send(:attributes=, attributes, true)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm-rails/multiparameter_attributes'
|
3
|
+
|
4
|
+
# Since multiparameters are a feature of Rails some tests are based on the test
|
5
|
+
# suite of Rails.
|
6
|
+
describe Rails::DataMapper::MultiparameterAttributes do
|
7
|
+
before :all do
|
8
|
+
load Pathname(__FILE__).dirname.parent.join('models/topic.rb').expand_path
|
9
|
+
load Pathname(__FILE__).dirname.parent.join('models/fake.rb').expand_path
|
10
|
+
model = ::Rails::DataMapper::Models::Topic
|
11
|
+
model.auto_migrate! if model.respond_to?(:auto_migrate!)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#attributes=' do
|
15
|
+
date_inputs = [
|
16
|
+
[ 'date',
|
17
|
+
{ 'last_read(1i)' => '2004', 'last_read(2i)' => '6', 'last_read(3i)' => '24' },
|
18
|
+
Date.new(2004, 6, 24) ],
|
19
|
+
[ 'date with empty year',
|
20
|
+
{ 'last_read(1i)' => '', 'last_read(2i)' => '6', 'last_read(3i)' => '24' },
|
21
|
+
Date.new(1, 6, 24) ],
|
22
|
+
[ 'date with empty month',
|
23
|
+
{ 'last_read(1i)' => '2004', 'last_read(2i)' => '', 'last_read(3i)' => '24' },
|
24
|
+
Date.new(2004, 1, 24) ],
|
25
|
+
[ 'date with empty day',
|
26
|
+
{ 'last_read(1i)' => '2004', 'last_read(2i)' => '6', 'last_read(3i)' => '' },
|
27
|
+
Date.new(2004, 6, 1) ],
|
28
|
+
[ 'date with empty day and year',
|
29
|
+
{ 'last_read(1i)' => '', 'last_read(2i)' => '6', 'last_read(3i)' => '' },
|
30
|
+
Date.new(1, 6, 1) ],
|
31
|
+
[ 'date with empty day and month',
|
32
|
+
{ 'last_read(1i)' => '2004', 'last_read(2i)' => '', 'last_read(3i)' => '' },
|
33
|
+
Date.new(2004, 1, 1) ],
|
34
|
+
[ 'date with empty year and month',
|
35
|
+
{ 'last_read(1i)' => '', 'last_read(2i)' => '', 'last_read(3i)' => '24' },
|
36
|
+
Date.new(1, 1, 24) ],
|
37
|
+
[ 'date with all empty',
|
38
|
+
{ 'last_read(1i)' => '', 'last_read(2i)' => '', 'last_read(3i)' => '' },
|
39
|
+
nil ],
|
40
|
+
]
|
41
|
+
|
42
|
+
date_inputs.each do |(name, attributes, date)|
|
43
|
+
it "converts #{name}" do
|
44
|
+
topic = ::Rails::DataMapper::Models::Topic.new
|
45
|
+
topic.attributes = attributes
|
46
|
+
topic.last_read.should == date
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
time_inputs = [
|
51
|
+
[ 'time',
|
52
|
+
{ 'written_on(1i)' => '2004', 'written_on(2i)' => '6', 'written_on(3i)' => '24',
|
53
|
+
'written_on(4i)' => '16', 'written_on(5i)' => '24', 'written_on(6i)' => '00' },
|
54
|
+
Time.local(2004, 6, 24, 16, 24, 0) ],
|
55
|
+
[ 'time with old date',
|
56
|
+
{ 'written_on(1i)' => '1901', 'written_on(2i)' => '12', 'written_on(3i)' => '31',
|
57
|
+
'written_on(4i)' => '23', 'written_on(5i)' => '59', 'written_on(6i)' => '59' },
|
58
|
+
Time.local(1901, 12, 31, 23, 59, 59) ],
|
59
|
+
[ 'time with all empty',
|
60
|
+
{ 'written_on(1i)' => '', 'written_on(2i)' => '', 'written_on(3i)' => '',
|
61
|
+
'written_on(4i)' => '', 'written_on(5i)' => '', 'written_on(6i)' => '' },
|
62
|
+
nil ],
|
63
|
+
[ 'time with empty seconds',
|
64
|
+
{ 'written_on(1i)' => '2004', 'written_on(2i)' => '6', 'written_on(3i)' => '24',
|
65
|
+
'written_on(4i)' => '16', 'written_on(5i)' => '24', 'written_on(6i)' => '' },
|
66
|
+
Time.local(2004, 6, 24, 16, 24, 0) ],
|
67
|
+
]
|
68
|
+
|
69
|
+
time_inputs.each do |(name, attributes, time)|
|
70
|
+
it "converts #{name}" do
|
71
|
+
topic = ::Rails::DataMapper::Models::Topic.new
|
72
|
+
topic.attributes = attributes
|
73
|
+
topic.written_on.should == time
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
date_time_inputs = [
|
78
|
+
[ 'datetime',
|
79
|
+
{ 'updated_at(1i)' => '2004', 'updated_at(2i)' => '6', 'updated_at(3i)' => '24',
|
80
|
+
'updated_at(4i)' => '16', 'updated_at(5i)' => '24', 'updated_at(6i)' => '00' },
|
81
|
+
DateTime.new(2004, 6, 24, 16, 24, 0) ],
|
82
|
+
]
|
83
|
+
|
84
|
+
date_time_inputs.each do |(name, attributes, time)|
|
85
|
+
it "converts #{name}" do
|
86
|
+
topic = ::Rails::DataMapper::Models::Topic.new
|
87
|
+
topic.attributes = attributes
|
88
|
+
topic.updated_at.should == time
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'calls super with merged multiparameters' do
|
93
|
+
multiparameter_hash = {
|
94
|
+
'composite(1)' => 'a string',
|
95
|
+
'composite(2)' => '1.5',
|
96
|
+
'composite(3i)' => '1.5',
|
97
|
+
'composite(4f)' => '1.5',
|
98
|
+
'composite(5)' => '',
|
99
|
+
'composite(6i)' => '',
|
100
|
+
'composite(7f)' => '',
|
101
|
+
}
|
102
|
+
attributes = { 'composite' => Object.new }
|
103
|
+
|
104
|
+
::Rails::DataMapper::Models::Composite.
|
105
|
+
should_receive(:new).
|
106
|
+
with('a string', '1.5', '1.5'.to_i, '1.5'.to_f).
|
107
|
+
and_return(attributes['composite'])
|
108
|
+
|
109
|
+
composite_property = mock(::DataMapper::Property)
|
110
|
+
composite_property.stub!(:primitive).and_return(::Rails::DataMapper::Models::Composite)
|
111
|
+
|
112
|
+
resource = ::Rails::DataMapper::Models::Fake.new
|
113
|
+
resource.stub!(:properties).and_return('composite' => composite_property)
|
114
|
+
|
115
|
+
resource.should_receive(:_super_attributes=).with(attributes)
|
116
|
+
|
117
|
+
resource.attributes = multiparameter_hash
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'raises exception on failure' do
|
121
|
+
multiparameter_hash = { 'composite(1)' => 'a string' }
|
122
|
+
attributes = { 'composite' => Object.new }
|
123
|
+
|
124
|
+
composite_exception = StandardError.new('foo')
|
125
|
+
::Rails::DataMapper::Models::Composite.
|
126
|
+
should_receive(:new).with('a string').and_raise(composite_exception)
|
127
|
+
|
128
|
+
composite_property = mock(::DataMapper::Property)
|
129
|
+
composite_property.stub!(:primitive).and_return(::Rails::DataMapper::Models::Composite)
|
130
|
+
|
131
|
+
resource = ::Rails::DataMapper::Models::Fake.new
|
132
|
+
resource.stub!(:properties).and_return('composite' => composite_property)
|
133
|
+
|
134
|
+
lambda { resource.attributes = multiparameter_hash }.
|
135
|
+
should raise_error(::Rails::DataMapper::MultiparameterAssignmentErrors) { |ex|
|
136
|
+
ex.errors.size.should == 1
|
137
|
+
|
138
|
+
error = ex.errors[0]
|
139
|
+
error.attribute.should == 'composite'
|
140
|
+
error.values.should == ['a string']
|
141
|
+
error.exception.should == composite_exception
|
142
|
+
}
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe 'new' do
|
147
|
+
it "merges multiparameters" do
|
148
|
+
attributes = {
|
149
|
+
'updated_at(1i)' => '2004', 'updated_at(2i)' => '6', 'updated_at(3i)' => '24',
|
150
|
+
'updated_at(4i)' => '16', 'updated_at(5i)' => '24', 'updated_at(6i)' => '00' }
|
151
|
+
|
152
|
+
topic = ::Rails::DataMapper::Models::Topic.new(attributes)
|
153
|
+
topic.updated_at.should == DateTime.new(2004, 6, 24, 16, 24, 0)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe 'create' do
|
158
|
+
it "merges multiparameters" do
|
159
|
+
attributes = {
|
160
|
+
'updated_at(1i)' => '2004', 'updated_at(2i)' => '6', 'updated_at(3i)' => '24',
|
161
|
+
'updated_at(4i)' => '16', 'updated_at(5i)' => '24', 'updated_at(6i)' => '00' }
|
162
|
+
|
163
|
+
topic = ::Rails::DataMapper::Models::Topic.create(attributes)
|
164
|
+
topic.updated_at.should == DateTime.new(2004, 6, 24, 16, 24, 0)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 4
|
10
|
-
version: 1.0.4
|
4
|
+
prerelease: 6
|
5
|
+
version: 1.1.0.rc1
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Martin Gamsjaeger (snusnu)
|
@@ -16,89 +11,108 @@ autorequire:
|
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
13
|
|
19
|
-
date:
|
14
|
+
date: 2011-02-28 00:00:00 -08:00
|
20
15
|
default_executable:
|
21
16
|
dependencies:
|
22
17
|
- !ruby/object:Gem::Dependency
|
23
|
-
name:
|
24
|
-
prerelease: false
|
18
|
+
name: actionpack
|
25
19
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
20
|
none: false
|
27
21
|
requirements:
|
28
22
|
- - ~>
|
29
23
|
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
segments:
|
32
|
-
- 1
|
33
|
-
- 0
|
34
|
-
- 0
|
35
|
-
version: 1.0.0
|
24
|
+
version: 3.0.4
|
36
25
|
type: :runtime
|
26
|
+
prerelease: false
|
37
27
|
version_requirements: *id001
|
38
28
|
- !ruby/object:Gem::Dependency
|
39
|
-
name:
|
40
|
-
prerelease: false
|
29
|
+
name: activesupport
|
41
30
|
requirement: &id002 !ruby/object:Gem::Requirement
|
42
31
|
none: false
|
43
32
|
requirements:
|
44
33
|
- - ~>
|
45
34
|
- !ruby/object:Gem::Version
|
46
|
-
|
47
|
-
segments:
|
48
|
-
- 1
|
49
|
-
- 0
|
50
|
-
- 3
|
51
|
-
version: 1.0.3
|
35
|
+
version: 3.0.4
|
52
36
|
type: :runtime
|
37
|
+
prerelease: false
|
53
38
|
version_requirements: *id002
|
54
39
|
- !ruby/object:Gem::Dependency
|
55
|
-
name:
|
56
|
-
prerelease: false
|
40
|
+
name: dm-core
|
57
41
|
requirement: &id003 !ruby/object:Gem::Requirement
|
58
42
|
none: false
|
59
43
|
requirements:
|
60
44
|
- - ~>
|
61
45
|
- !ruby/object:Gem::Version
|
62
|
-
|
63
|
-
segments:
|
64
|
-
- 3
|
65
|
-
- 0
|
66
|
-
- 0
|
67
|
-
version: 3.0.0
|
46
|
+
version: 1.0.2
|
68
47
|
type: :runtime
|
48
|
+
prerelease: false
|
69
49
|
version_requirements: *id003
|
70
50
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
72
|
-
prerelease: false
|
51
|
+
name: dm-active_model
|
73
52
|
requirement: &id004 !ruby/object:Gem::Requirement
|
74
53
|
none: false
|
75
54
|
requirements:
|
76
55
|
- - ~>
|
77
56
|
- !ruby/object:Gem::Version
|
78
|
-
|
79
|
-
segments:
|
80
|
-
- 3
|
81
|
-
- 0
|
82
|
-
- 0
|
83
|
-
version: 3.0.0
|
57
|
+
version: 1.0.2
|
84
58
|
type: :runtime
|
59
|
+
prerelease: false
|
85
60
|
version_requirements: *id004
|
86
61
|
- !ruby/object:Gem::Dependency
|
87
|
-
name:
|
88
|
-
prerelease: false
|
62
|
+
name: i18n
|
89
63
|
requirement: &id005 !ruby/object:Gem::Requirement
|
90
64
|
none: false
|
91
65
|
requirements:
|
92
66
|
- - ~>
|
93
67
|
- !ruby/object:Gem::Version
|
94
|
-
|
95
|
-
segments:
|
96
|
-
- 3
|
97
|
-
- 0
|
98
|
-
- 0
|
99
|
-
version: 3.0.0
|
68
|
+
version: 0.5.0
|
100
69
|
type: :runtime
|
70
|
+
prerelease: false
|
101
71
|
version_requirements: *id005
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: railties
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 3.0.4
|
80
|
+
type: :runtime
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: *id006
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: jeweler
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.5.2
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: *id007
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rake
|
96
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.8.7
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: *id008
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: rspec
|
107
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ~>
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 1.3.1
|
113
|
+
type: :development
|
114
|
+
prerelease: false
|
115
|
+
version_requirements: *id009
|
102
116
|
description: Integrate DataMapper with Rails 3
|
103
117
|
email: gamsnjaga@gmail.com
|
104
118
|
executables: []
|
@@ -110,7 +124,6 @@ extra_rdoc_files:
|
|
110
124
|
- README.rdoc
|
111
125
|
files:
|
112
126
|
- .document
|
113
|
-
- .gitignore
|
114
127
|
- Gemfile
|
115
128
|
- LICENSE
|
116
129
|
- README.rdoc
|
@@ -121,6 +134,7 @@ files:
|
|
121
134
|
- lib/dm-rails/configuration.rb
|
122
135
|
- lib/dm-rails/mass_assignment_security.rb
|
123
136
|
- lib/dm-rails/middleware/identity_map.rb
|
137
|
+
- lib/dm-rails/multiparameter_attributes.rb
|
124
138
|
- lib/dm-rails/railtie.rb
|
125
139
|
- lib/dm-rails/railties/controller_runtime.rb
|
126
140
|
- lib/dm-rails/railties/database.rake
|
@@ -137,10 +151,13 @@ files:
|
|
137
151
|
- lib/generators/data_mapper/model/templates/model.rb
|
138
152
|
- lib/generators/data_mapper/observer/observer_generator.rb
|
139
153
|
- lib/generators/data_mapper/observer/templates/observer.rb
|
140
|
-
-
|
154
|
+
- spec/models/fake.rb
|
155
|
+
- spec/models/topic.rb
|
156
|
+
- spec/spec.opts
|
157
|
+
- spec/spec_helper.rb
|
158
|
+
- spec/unit/mass_assignment_security_spec.rb
|
159
|
+
- spec/unit/multiparameter_attributes_spec.rb
|
141
160
|
- tasks/clean.rake
|
142
|
-
- tasks/local_gemfile.rake
|
143
|
-
- tasks/metrics.rake
|
144
161
|
- tasks/yard.rake
|
145
162
|
- tasks/yardstick.rake
|
146
163
|
has_rdoc: true
|
@@ -148,8 +165,8 @@ homepage: http://github.com/datamapper/dm-rails
|
|
148
165
|
licenses: []
|
149
166
|
|
150
167
|
post_install_message:
|
151
|
-
rdoc_options:
|
152
|
-
|
168
|
+
rdoc_options: []
|
169
|
+
|
153
170
|
require_paths:
|
154
171
|
- lib
|
155
172
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -157,25 +174,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
157
174
|
requirements:
|
158
175
|
- - ">="
|
159
176
|
- !ruby/object:Gem::Version
|
160
|
-
hash: 3
|
161
|
-
segments:
|
162
|
-
- 0
|
163
177
|
version: "0"
|
164
178
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
179
|
none: false
|
166
180
|
requirements:
|
167
|
-
- - "
|
181
|
+
- - ">"
|
168
182
|
- !ruby/object:Gem::Version
|
169
|
-
|
170
|
-
segments:
|
171
|
-
- 0
|
172
|
-
version: "0"
|
183
|
+
version: 1.3.1
|
173
184
|
requirements: []
|
174
185
|
|
175
186
|
rubyforge_project: datamapper
|
176
|
-
rubygems_version: 1.
|
187
|
+
rubygems_version: 1.5.2
|
177
188
|
signing_key:
|
178
189
|
specification_version: 3
|
179
190
|
summary: Use DataMapper with Rails 3
|
180
|
-
test_files:
|
181
|
-
|
191
|
+
test_files:
|
192
|
+
- spec/models/fake.rb
|
193
|
+
- spec/models/topic.rb
|
194
|
+
- spec/spec_helper.rb
|
195
|
+
- spec/unit/mass_assignment_security_spec.rb
|
196
|
+
- spec/unit/multiparameter_attributes_spec.rb
|
data/.gitignore
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
## MAC OS
|
2
|
-
.DS_Store
|
3
|
-
|
4
|
-
## TEXTMATE
|
5
|
-
*.tmproj
|
6
|
-
tmtags
|
7
|
-
|
8
|
-
## EMACS
|
9
|
-
*~
|
10
|
-
\#*
|
11
|
-
.\#*
|
12
|
-
|
13
|
-
## VIM
|
14
|
-
*.swp
|
15
|
-
|
16
|
-
## Rubinius
|
17
|
-
*.rbc
|
18
|
-
|
19
|
-
## PROJECT::GENERAL
|
20
|
-
*.gem
|
21
|
-
coverage
|
22
|
-
rdoc
|
23
|
-
pkg
|
24
|
-
tmp
|
25
|
-
doc
|
26
|
-
log
|
27
|
-
.yardoc
|
28
|
-
measurements
|
29
|
-
|
30
|
-
## BUNDLER
|
31
|
-
.bundle
|
32
|
-
Gemfile.local
|
33
|
-
Gemfile.lock
|
34
|
-
Gemfile.local.lock
|
35
|
-
|
36
|
-
## PROJECT::SPECIFIC
|
37
|
-
vendor
|
data/tasks/ci.rake
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
task :ci => [ 'metrics:all' ]
|
data/tasks/local_gemfile.rake
DELETED
@@ -1,16 +0,0 @@
|
|
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
|
-
root.join('Gemfile.local').open('w') do |f|
|
8
|
-
root.join('Gemfile').open.each do |line|
|
9
|
-
line.sub!(/DATAMAPPER = 'git:\/\/github.com\/datamapper'/, "DATAMAPPER = '#{datamapper}'")
|
10
|
-
line.sub!(/:git => \"#\{DATAMAPPER\}\/(.+?)(?:\.git)?\"/, ':path => "#{DATAMAPPER}/\1"')
|
11
|
-
line.sub!(/do_options\[:git\] = \"#\{DATAMAPPER\}\/(.+?)(?:\.git)?\"/, 'do_options[:path] = "#{DATAMAPPER}/\1"')
|
12
|
-
f.puts line
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
data/tasks/metrics.rake
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'metric_fu'
|
3
|
-
rescue LoadError
|
4
|
-
namespace :metrics do
|
5
|
-
task :all do
|
6
|
-
abort 'metric_fu is not available. In order to run metrics:all, you must: gem install metric_fu'
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
begin
|
12
|
-
require 'reek/adapters/rake_task'
|
13
|
-
|
14
|
-
Reek::RakeTask.new do |t|
|
15
|
-
t.fail_on_error = true
|
16
|
-
t.verbose = false
|
17
|
-
t.source_files = 'lib/**/*.rb'
|
18
|
-
end
|
19
|
-
rescue LoadError
|
20
|
-
task :reek do
|
21
|
-
abort 'Reek is not available. In order to run reek, you must: gem install reek'
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
begin
|
26
|
-
require 'roodi'
|
27
|
-
require 'rake/tasklib'
|
28
|
-
require 'roodi_task'
|
29
|
-
|
30
|
-
RoodiTask.new do |t|
|
31
|
-
t.verbose = false
|
32
|
-
end
|
33
|
-
rescue LoadError
|
34
|
-
task :roodi do
|
35
|
-
abort 'Roodi is not available. In order to run roodi, you must: gem install roodi'
|
36
|
-
end
|
37
|
-
end
|