ardm-rails 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.gitignore +35 -0
- data/.travis.yml +11 -0
- data/Gemfile +47 -0
- data/LICENSE +20 -0
- data/README.rdoc +595 -0
- data/Rakefile +4 -0
- data/VERSION +1 -0
- data/ardm-rails.gemspec +27 -0
- data/lib/ardm-rails.rb +1 -0
- data/lib/dm-rails/configuration.rb +76 -0
- data/lib/dm-rails/mass_assignment_security.rb +89 -0
- data/lib/dm-rails/middleware/identity_map.rb +20 -0
- data/lib/dm-rails/multiparameter_attributes.rb +167 -0
- data/lib/dm-rails/railtie.rb +100 -0
- data/lib/dm-rails/railties/controller_runtime.rb +45 -0
- data/lib/dm-rails/railties/database.rake +106 -0
- data/lib/dm-rails/railties/i18n_support.rb +12 -0
- data/lib/dm-rails/railties/log_listener.rb +39 -0
- data/lib/dm-rails/railties/log_subscriber.rb +54 -0
- data/lib/dm-rails/session_store.rb +70 -0
- data/lib/dm-rails/setup.rb +84 -0
- data/lib/dm-rails/storage.rb +209 -0
- data/lib/dm-rails/version.rb +5 -0
- data/lib/dm-rails.rb +1 -0
- data/lib/generators/data_mapper/migration/migration_generator.rb +30 -0
- data/lib/generators/data_mapper/migration/templates/migration.rb +23 -0
- data/lib/generators/data_mapper/model/model_generator.rb +23 -0
- data/lib/generators/data_mapper/model/templates/model.rb +11 -0
- data/lib/generators/data_mapper/observer/observer_generator.rb +19 -0
- data/lib/generators/data_mapper/observer/templates/observer.rb +7 -0
- data/lib/generators/data_mapper.rb +82 -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 +168 -0
- data/tasks/clean.rake +6 -0
- data/tasks/spec.rake +17 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +20 -0
- metadata +188 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Railties
|
3
|
+
|
4
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
5
|
+
|
6
|
+
def self.runtime=(value)
|
7
|
+
Thread.current["data_mapper_sql_runtime"] = value
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.runtime
|
11
|
+
Thread.current["data_mapper_sql_runtime"] ||= 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.reset_runtime
|
15
|
+
rt, self.runtime = runtime, 0
|
16
|
+
rt
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
super
|
21
|
+
@odd_or_even = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def sql(event)
|
25
|
+
self.class.runtime += event.duration
|
26
|
+
return unless logger.debug?
|
27
|
+
|
28
|
+
name = '%s (%.3fms)' % [event.payload[:name], event.duration]
|
29
|
+
sql = event.payload[:sql].squeeze(' ')
|
30
|
+
|
31
|
+
if odd?
|
32
|
+
name = color(name, CYAN, true)
|
33
|
+
sql = color(sql, nil, true)
|
34
|
+
else
|
35
|
+
name = color(name, MAGENTA, true)
|
36
|
+
end
|
37
|
+
|
38
|
+
debug " #{name} #{sql}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def odd?
|
42
|
+
@odd_or_even = !@odd_or_even
|
43
|
+
end
|
44
|
+
|
45
|
+
def logger
|
46
|
+
::DataMapper.logger
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
DataMapper::Railties::LogSubscriber.attach_to :data_mapper
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'active_support/core_ext/class/attribute'
|
3
|
+
|
4
|
+
# Implements DataMapper-specific session store.
|
5
|
+
|
6
|
+
module Rails
|
7
|
+
module DataMapper
|
8
|
+
|
9
|
+
class SessionStore < ActionDispatch::Session::AbstractStore
|
10
|
+
|
11
|
+
class Session
|
12
|
+
|
13
|
+
include ::DataMapper::Resource
|
14
|
+
|
15
|
+
property :id, Serial
|
16
|
+
property :session_id, String, :required => true, :unique => true
|
17
|
+
property :data, Object, :required => true
|
18
|
+
property :updated_at, DateTime, :index => true
|
19
|
+
|
20
|
+
def self.name
|
21
|
+
'session'
|
22
|
+
end
|
23
|
+
|
24
|
+
def data
|
25
|
+
attribute_get(:data) || {}
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
SESSION_RECORD_KEY = 'rack.session.record'.freeze
|
31
|
+
|
32
|
+
class_attribute :session_class
|
33
|
+
self.session_class = Session
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def get_session(env, sid)
|
38
|
+
sid ||= generate_sid
|
39
|
+
session = find_session(sid)
|
40
|
+
env[SESSION_RECORD_KEY] = session
|
41
|
+
[ sid, session.data ]
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_session(env, sid, session_data)
|
45
|
+
session = get_session_resource(env, sid)
|
46
|
+
session.data = session_data
|
47
|
+
session.updated_at = DateTime.now if session.dirty?
|
48
|
+
session.save ? sid : false
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_session_resource(env, sid)
|
52
|
+
if env[ENV_SESSION_OPTIONS_KEY][:id].nil?
|
53
|
+
env[SESSION_RECORD_KEY] = find_session(sid)
|
54
|
+
else
|
55
|
+
env[SESSION_RECORD_KEY] ||= find_session(sid)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_session(sid)
|
60
|
+
self.class.session_class.first_or_new(:session_id => sid)
|
61
|
+
end
|
62
|
+
|
63
|
+
def destroy(env)
|
64
|
+
find_session(current_session_id(env)).destroy
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'active_support/core_ext/hash/except'
|
2
|
+
|
3
|
+
require 'dm-rails/configuration'
|
4
|
+
require 'dm-rails/railties/log_listener'
|
5
|
+
|
6
|
+
module Rails
|
7
|
+
module DataMapper
|
8
|
+
|
9
|
+
def self.setup(environment)
|
10
|
+
::DataMapper.logger.info "[datamapper] Setting up the #{environment.inspect} environment:"
|
11
|
+
configuration.repositories[environment].each do |name, config|
|
12
|
+
setup_with_instrumentation(name.to_sym, config)
|
13
|
+
end
|
14
|
+
finalize
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.setup_with_instrumentation(name, options)
|
18
|
+
|
19
|
+
adapter = if options['uri']
|
20
|
+
database_uri = ::Addressable::URI.parse(options['uri'])
|
21
|
+
::DataMapper.logger.info "[datamapper] Setting up #{name.inspect} repository: '#{database_uri.path}' on #{database_uri.scheme}"
|
22
|
+
::DataMapper.setup(name, database_uri)
|
23
|
+
else
|
24
|
+
::DataMapper.logger.info "[datamapper] Setting up #{name.inspect} repository: '#{options['database']}' on #{options['adapter']}"
|
25
|
+
::DataMapper.setup(name, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
if convention = configuration.resource_naming_convention[name]
|
29
|
+
adapter.resource_naming_convention = convention
|
30
|
+
end
|
31
|
+
if convention = configuration.field_naming_convention[name]
|
32
|
+
adapter.field_naming_convention = convention
|
33
|
+
end
|
34
|
+
setup_log_listener(adapter.options['adapter'])
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.setup_logger(logger)
|
38
|
+
::DataMapper.logger = logger
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.setup_log_listener(adapter_name)
|
42
|
+
adapter_name = 'sqlite3' if adapter_name == 'sqlite'
|
43
|
+
driver_name = ActiveSupport::Inflector.camelize(adapter_name)
|
44
|
+
|
45
|
+
setup_do_driver(driver_name) do |driver|
|
46
|
+
DataObjects::Connection.send(:include, LogListener)
|
47
|
+
# FIXME Setting DataMapper::Logger.new($stdout, :off) alone won't work because the #log
|
48
|
+
# method is currently only available in DO and needs an explicit DO Logger instantiated.
|
49
|
+
# We turn the logger :off because ActiveSupport::Notifications handles displaying log messages
|
50
|
+
driver.logger = DataObjects::Logger.new($stdout, :off)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.finalize
|
55
|
+
::DataMapper.finalize
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.preload_models(app)
|
59
|
+
app.config.paths['app/models'].each do |path|
|
60
|
+
Dir.glob("#{path}/**/*.rb").sort.each { |file| require_dependency file[path.length..-1] }
|
61
|
+
end
|
62
|
+
finalize
|
63
|
+
end
|
64
|
+
|
65
|
+
class << self
|
66
|
+
private
|
67
|
+
|
68
|
+
if RUBY_VERSION < '1.9'
|
69
|
+
def setup_do_driver(driver_name)
|
70
|
+
if Object.const_defined?('DataObjects') && DataObjects.const_defined?(driver_name)
|
71
|
+
yield DataObjects.const_get(driver_name)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
else
|
75
|
+
def setup_do_driver(driver_name)
|
76
|
+
if Object.const_defined?('DataObjects', false) && DataObjects.const_defined?(driver_name, false)
|
77
|
+
yield DataObjects.const_get(driver_name, false)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
module Rails
|
2
|
+
module DataMapper
|
3
|
+
|
4
|
+
def self.storage
|
5
|
+
Storage
|
6
|
+
end
|
7
|
+
|
8
|
+
class Storage
|
9
|
+
attr_reader :name, :config
|
10
|
+
|
11
|
+
def self.create_all
|
12
|
+
with_local_repositories { |config| create_environment(config) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.drop_all
|
16
|
+
with_local_repositories { |config| drop_environment(config) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.create_environment(config)
|
20
|
+
config.each { |repo_name, repo_config| new(repo_name, repo_config).create }
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.drop_environment(config)
|
24
|
+
config.each { |repo_name, repo_config| new(repo_name, repo_config).drop }
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.new(name, config)
|
28
|
+
klass = lookup_class(config['adapter'])
|
29
|
+
if klass.equal?(self)
|
30
|
+
super(name, config)
|
31
|
+
else
|
32
|
+
klass.new(name, config)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class << self
|
37
|
+
private
|
38
|
+
|
39
|
+
def with_local_repositories
|
40
|
+
Rails::DataMapper.configuration.repositories.each_value do |config|
|
41
|
+
if config['host'].blank? || %w[ 127.0.0.1 localhost ].include?(config['host'])
|
42
|
+
yield(config)
|
43
|
+
else
|
44
|
+
puts "This task only modifies local databases. #{config['database']} is on a remote host."
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def lookup_class(adapter)
|
50
|
+
klass_name = normalized_adapter_name(adapter).camelize.to_sym
|
51
|
+
|
52
|
+
unless Storage.const_defined?(klass_name)
|
53
|
+
raise "Adapter #{adapter} not supported (#{klass_name.inspect})"
|
54
|
+
end
|
55
|
+
|
56
|
+
const_get(klass_name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def normalized_adapter_name(adapter_name)
|
60
|
+
adapter_name.to_s == 'sqlite3' ? 'sqlite' : adapter_name
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize(name, config)
|
66
|
+
@name, @config = name.to_sym, config
|
67
|
+
end
|
68
|
+
|
69
|
+
def create
|
70
|
+
puts create_message if _create
|
71
|
+
end
|
72
|
+
|
73
|
+
def drop
|
74
|
+
puts drop_message if _drop
|
75
|
+
end
|
76
|
+
|
77
|
+
def database
|
78
|
+
@database ||= config['database'] || config['path']
|
79
|
+
end
|
80
|
+
|
81
|
+
def username
|
82
|
+
@username ||= config['username'] || ''
|
83
|
+
end
|
84
|
+
|
85
|
+
def password
|
86
|
+
@password ||= config['password'] || ''
|
87
|
+
end
|
88
|
+
|
89
|
+
def charset
|
90
|
+
@charset ||= config['charset'] || ENV['CHARSET'] || 'utf8'
|
91
|
+
end
|
92
|
+
|
93
|
+
def create_message
|
94
|
+
"[datamapper] Created database '#{database}'"
|
95
|
+
end
|
96
|
+
|
97
|
+
def drop_message
|
98
|
+
"[datamapper] Dropped database '#{database}'"
|
99
|
+
end
|
100
|
+
|
101
|
+
# Create the configured database
|
102
|
+
#
|
103
|
+
# This is a noop so that calling this method
|
104
|
+
# won't explode on people who use adapters that
|
105
|
+
# don't support creating a storage recepticle
|
106
|
+
def _create
|
107
|
+
true
|
108
|
+
end
|
109
|
+
|
110
|
+
# Drop the configured database
|
111
|
+
#
|
112
|
+
# This is a noop so that calling this method
|
113
|
+
# won't explode on people who use adapters that
|
114
|
+
# don't support dropping a storage recepticle
|
115
|
+
def _drop
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
class Sqlite < Storage
|
120
|
+
|
121
|
+
# This is a noop for sqlite
|
122
|
+
#
|
123
|
+
# Overwritten solely for documentation purposes
|
124
|
+
#
|
125
|
+
# Both auto_migrate!/auto_upgrade! will create the actual database
|
126
|
+
# if the connection has been setup properly and there actually
|
127
|
+
# are statements to execute (i.e. at least one model is declared)
|
128
|
+
#
|
129
|
+
# DataMapper.setup alone won't create the actual database so there
|
130
|
+
# really is no API to simply create an empty database for sqlite3.
|
131
|
+
#
|
132
|
+
# we return true to indicate success nevertheless
|
133
|
+
def _create
|
134
|
+
true
|
135
|
+
end
|
136
|
+
|
137
|
+
def _drop
|
138
|
+
return if in_memory?
|
139
|
+
path.unlink if path.file?
|
140
|
+
end
|
141
|
+
|
142
|
+
def create_message
|
143
|
+
"[datamapper] db:create is a noop for sqlite3, use db:automigrate instead (#{database})"
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def in_memory?
|
149
|
+
database == ':memory:'
|
150
|
+
end
|
151
|
+
|
152
|
+
def path
|
153
|
+
@path ||= Pathname(File.expand_path(database, Rails.root))
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
class Mysql < Storage
|
159
|
+
def _create
|
160
|
+
execute("CREATE DATABASE `#{database}` DEFAULT CHARACTER SET #{charset} DEFAULT COLLATE #{collation}")
|
161
|
+
end
|
162
|
+
|
163
|
+
def _drop
|
164
|
+
execute("DROP DATABASE IF EXISTS `#{database}`")
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
def execute(statement)
|
170
|
+
system(
|
171
|
+
'mysql',
|
172
|
+
(username.blank? ? '' : "--user=#{username}"),
|
173
|
+
(password.blank? ? '' : "--password=#{password}"),
|
174
|
+
'-e',
|
175
|
+
statement
|
176
|
+
)
|
177
|
+
end
|
178
|
+
|
179
|
+
def collation
|
180
|
+
@collation ||= config['collation'] || ENV['COLLATION'] || 'utf8_unicode_ci'
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
class Postgres < Storage
|
186
|
+
def _create
|
187
|
+
system(
|
188
|
+
'createdb',
|
189
|
+
'-E',
|
190
|
+
charset,
|
191
|
+
'-U',
|
192
|
+
username,
|
193
|
+
database
|
194
|
+
)
|
195
|
+
end
|
196
|
+
|
197
|
+
def _drop
|
198
|
+
system(
|
199
|
+
'dropdb',
|
200
|
+
'-U',
|
201
|
+
username,
|
202
|
+
database
|
203
|
+
)
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
data/lib/dm-rails.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'dm-rails/railtie'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'generators/data_mapper'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Generators
|
5
|
+
|
6
|
+
class MigrationGenerator < Base
|
7
|
+
|
8
|
+
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
9
|
+
class_option :id, :type => :numeric, :desc => "The id to be used in this migration"
|
10
|
+
|
11
|
+
def create_migration_file
|
12
|
+
set_local_assigns!
|
13
|
+
migration_template "migration.rb", "db/migrate/#{file_name}.rb"
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
attr_reader :migration_action
|
19
|
+
|
20
|
+
def set_local_assigns!
|
21
|
+
if file_name =~ /^(add|remove|drop)_.*_(?:to|from)_(.*)/
|
22
|
+
@migration_action = $1 == 'add' ? 'add' : 'drop'
|
23
|
+
@table_name = $2.pluralize
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
migration <%= migration_number.to_i %>, :<%= migration_file_name %> do
|
2
|
+
|
3
|
+
up do
|
4
|
+
<% unless attributes.empty? -%>
|
5
|
+
modify_table :<%= table_name %> do
|
6
|
+
<% attributes.each do |attribute| -%>
|
7
|
+
<%= migration_action %>_column :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type_class %><% end -%>
|
8
|
+
<% end -%>
|
9
|
+
end
|
10
|
+
<% end -%>
|
11
|
+
end
|
12
|
+
|
13
|
+
down do
|
14
|
+
<% unless attributes.empty? -%>
|
15
|
+
modify_table :<%= table_name %> do
|
16
|
+
<% attributes.reverse.each do |attribute| -%>
|
17
|
+
<%= migration_action == 'add' ? 'drop' : 'add' %>_column :<%= attribute.name %><% if migration_action == 'drop' %>, :<%= attribute.type_class %><% end -%>
|
18
|
+
<% end -%>
|
19
|
+
end
|
20
|
+
<% end -%>
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'generators/data_mapper'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Generators
|
5
|
+
|
6
|
+
class ModelGenerator < Base
|
7
|
+
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
8
|
+
|
9
|
+
check_class_collision
|
10
|
+
|
11
|
+
class_option :timestamps, :type => :boolean
|
12
|
+
class_option :parent, :type => :string, :desc => "The parent class for the generated model"
|
13
|
+
|
14
|
+
def create_model_file
|
15
|
+
template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
16
|
+
end
|
17
|
+
|
18
|
+
hook_for :test_framework
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class <%= class_name %><%= "< #{options[:parent].classify}" if options[:parent] %>
|
2
|
+
|
3
|
+
<% unless options[:parent] -%>
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id, Serial
|
7
|
+
<% end %>
|
8
|
+
<% attributes.each do |attribute| -%>
|
9
|
+
property :<%= attribute.name -%>, <%= attribute.type_class %>
|
10
|
+
<% end %>
|
11
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'generators/data_mapper'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Generators
|
5
|
+
|
6
|
+
class ObserverGenerator < Base
|
7
|
+
|
8
|
+
check_class_collision :suffix => "Observer"
|
9
|
+
|
10
|
+
def create_observer_file
|
11
|
+
template 'observer.rb', File.join('app/models', class_path, "#{file_name}_observer.rb")
|
12
|
+
end
|
13
|
+
|
14
|
+
hook_for :test_framework
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'rails/generators/named_base'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
require 'rails/generators/active_model'
|
4
|
+
|
5
|
+
module DataMapper
|
6
|
+
module Generators
|
7
|
+
|
8
|
+
class Base < ::Rails::Generators::NamedBase #:nodoc:
|
9
|
+
|
10
|
+
include ::Rails::Generators::Migration
|
11
|
+
|
12
|
+
def self.source_root
|
13
|
+
@_datamapper_source_root ||=
|
14
|
+
File.expand_path("../#{base_name}/#{generator_name}/templates", __FILE__)
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
# Datamapper does not care if migrations have the same name as long as
|
20
|
+
# they have different ids.
|
21
|
+
#
|
22
|
+
def migration_exists?(dirname, file_name) #:nodoc:
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
# Implement the required interface for Rails::Generators::Migration.
|
27
|
+
#
|
28
|
+
def self.next_migration_number(dirname) #:nodoc:
|
29
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class ActiveModel < ::Rails::Generators::ActiveModel #:nodoc:
|
35
|
+
def self.all(klass)
|
36
|
+
"#{klass}.all"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.find(klass, params=nil)
|
40
|
+
"#{klass}.get(#{params})"
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.build(klass, params=nil)
|
44
|
+
if params
|
45
|
+
"#{klass}.new(#{params})"
|
46
|
+
else
|
47
|
+
"#{klass}.new"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def save
|
52
|
+
"#{name}.save"
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_attributes(params=nil)
|
56
|
+
"#{name}.update(#{params})"
|
57
|
+
end
|
58
|
+
|
59
|
+
def errors
|
60
|
+
"#{name}.errors"
|
61
|
+
end
|
62
|
+
|
63
|
+
def destroy
|
64
|
+
"#{name}.destroy"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module Rails
|
72
|
+
|
73
|
+
module Generators
|
74
|
+
class GeneratedAttribute #:nodoc:
|
75
|
+
def type_class
|
76
|
+
return 'DateTime' if type.to_s == 'datetime'
|
77
|
+
return type.to_s.camelcase
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
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
|