merb-admin 0.5.7 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/app/controllers/main.rb +11 -14
- data/lib/abstract_model.rb +14 -0
- data/lib/activerecord_support.rb +6 -5
- data/lib/datamapper_support.rb +8 -5
- data/lib/merb-admin/slicetasks.rb +23 -2
- data/lib/merb-admin.rb +1 -1
- data/lib/sequel_support.rb +309 -0
- data/spec/migrations/sequel/001_create_divisions_migration.rb +15 -0
- data/spec/migrations/sequel/002_create_drafts_migration.rb +21 -0
- data/spec/migrations/sequel/003_create_leagues_migration.rb +14 -0
- data/spec/migrations/sequel/004_create_players_migration.rb +22 -0
- data/spec/migrations/sequel/005_create_teams_migration.rb +24 -0
- data/spec/models/sequel/division.rb +15 -0
- data/spec/models/sequel/draft.rb +19 -0
- data/spec/models/sequel/league.rb +14 -0
- data/spec/models/sequel/player.rb +18 -0
- data/spec/models/sequel/team.rb +22 -0
- data/spec/requests/main_spec.rb +6 -0
- data/spec/spec_helper.rb +4 -0
- metadata +12 -1
data/README.rdoc
CHANGED
@@ -6,7 +6,7 @@ The status of the latest build is available here[http://runcoderun.com/sferik/me
|
|
6
6
|
== Installation
|
7
7
|
$ gem install merb-admin -s http://gemcutter.org
|
8
8
|
In your app, add the following dependency to <tt>config/dependencies.rb</tt>:
|
9
|
-
dependency "merb-admin", "0.
|
9
|
+
dependency "merb-admin", "0.6.0"
|
10
10
|
Add the following route to <tt>config/router.rb</tt>:
|
11
11
|
add_slice(:merb_admin, :path_prefix => "admin")
|
12
12
|
Then, run the following rake task:
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ AUTHOR = "Erik Michaels-Ober"
|
|
9
9
|
EMAIL = "sferik@gmail.com"
|
10
10
|
HOMEPAGE = "http://github.com/sferik/merb-admin"
|
11
11
|
SUMMARY = "MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data."
|
12
|
-
GEM_VERSION = "0.
|
12
|
+
GEM_VERSION = "0.6.0"
|
13
13
|
|
14
14
|
spec = Gem::Specification.new do |s|
|
15
15
|
s.rubyforge_project = "merb"
|
data/app/controllers/main.rb
CHANGED
@@ -58,7 +58,7 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
58
58
|
has_one_associations = @abstract_model.has_one_associations.map{|association| [association, (params[:associations] || {}).delete(association[:name])]}
|
59
59
|
has_many_associations = @abstract_model.has_many_associations.map{|association| [association, (params[:associations] || {}).delete(association[:name])]}
|
60
60
|
@object = @abstract_model.new(object)
|
61
|
-
if @object.save && has_one_associations.each{|association, id|
|
61
|
+
if @object.save && has_one_associations.each{|association, id| update_association(association, id)} && has_many_associations.each{|association, ids| update_associations(association, ids.to_a)}
|
62
62
|
if params[:_continue]
|
63
63
|
redirect(url(:merb_admin_edit, :model_name => @abstract_model.singular_name, :id => @object.id), :message => {:notice => "#{@abstract_model.pretty_name} was successfully created"})
|
64
64
|
elsif params[:_add_another]
|
@@ -80,7 +80,7 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
80
80
|
end
|
81
81
|
has_one_associations = @abstract_model.has_one_associations.map{|association| [association, (params[:associations] || {}).delete(association[:name])]}
|
82
82
|
has_many_associations = @abstract_model.has_many_associations.map{|association| [association, (params[:associations] || {}).delete(association[:name])]}
|
83
|
-
if @object.update_attributes(object) && has_one_associations.each{|association, id|
|
83
|
+
if @object.update_attributes(object) && has_one_associations.each{|association, id| update_association(association, id)} && has_many_associations.each{|association, ids| update_associations(association, ids.to_a)}
|
84
84
|
if params[:_continue]
|
85
85
|
redirect(url(:merb_admin_edit, :model_name => @abstract_model.singular_name, :id => @object.id), :message => {:notice => "#{@abstract_model.pretty_name} was successfully updated"})
|
86
86
|
elsif params[:_add_another]
|
@@ -174,23 +174,20 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
174
174
|
options.merge!(:sort_reverse => reverse)
|
175
175
|
end
|
176
176
|
|
177
|
-
def
|
178
|
-
|
179
|
-
if object =
|
177
|
+
def update_association(association, id = nil)
|
178
|
+
associated_model = MerbAdmin::AbstractModel.new(association[:child_model])
|
179
|
+
if object = associated_model.get(id)
|
180
180
|
object.update_attributes(association[:child_key].first => @object.id)
|
181
181
|
end
|
182
182
|
end
|
183
183
|
|
184
|
-
def
|
185
|
-
|
186
|
-
|
187
|
-
@object.clear_association(relationship)
|
188
|
-
# Add all of the objects to the relationship
|
189
|
-
model = MerbAdmin::AbstractModel.new(association[:child_model])
|
190
|
-
for object in model.all_in(ids)
|
191
|
-
relationship << object
|
192
|
-
end
|
184
|
+
def update_associations(association, ids = [])
|
185
|
+
associated_object = @object.send(association[:name])
|
186
|
+
@object.clear_association(associated_object)
|
193
187
|
@object.save
|
188
|
+
ids.each do |id|
|
189
|
+
update_association(association, id)
|
190
|
+
end
|
194
191
|
end
|
195
192
|
|
196
193
|
end
|
data/lib/abstract_model.rb
CHANGED
@@ -24,6 +24,15 @@ module MerbAdmin
|
|
24
24
|
@models << new(model) if model
|
25
25
|
end
|
26
26
|
@models.sort!{|a, b| a.model.to_s <=> b.model.to_s}
|
27
|
+
when :sequel
|
28
|
+
Dir.glob(Merb.dir_for(:model) / Merb.glob_for(:model)).each do |filename|
|
29
|
+
# FIXME: This heuristic for finding Sequel models could be too strict
|
30
|
+
File.read(filename).scan(/^class ([\w\d_\-:]+) < Sequel::Model$/).flatten.each do |m|
|
31
|
+
model = lookup(m.to_s.to_sym)
|
32
|
+
@models << new(model) if model
|
33
|
+
end
|
34
|
+
end
|
35
|
+
@models.sort!{|a, b| a.model.to_s <=> b.model.to_s}
|
27
36
|
else
|
28
37
|
raise "MerbAdmin does not support the #{Merb.orm} ORM"
|
29
38
|
end
|
@@ -42,6 +51,8 @@ module MerbAdmin
|
|
42
51
|
return model if model.superclass == ActiveRecord::Base
|
43
52
|
when :datamapper
|
44
53
|
return model if model.include?(DataMapper::Resource)
|
54
|
+
when :sequel
|
55
|
+
return model if model.superclass == Sequel::Model
|
45
56
|
end
|
46
57
|
nil
|
47
58
|
end
|
@@ -59,6 +70,9 @@ module MerbAdmin
|
|
59
70
|
when :datamapper
|
60
71
|
require 'datamapper_support'
|
61
72
|
self.extend(DatamapperSupport)
|
73
|
+
when :sequel
|
74
|
+
require 'sequel_support'
|
75
|
+
self.extend(SequelSupport)
|
62
76
|
else
|
63
77
|
raise "MerbAdmin does not support the #{Merb.orm} ORM"
|
64
78
|
end
|
data/lib/activerecord_support.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'activerecord'
|
2
|
+
|
1
3
|
module MerbAdmin
|
2
4
|
class AbstractModel
|
3
5
|
module ActiverecordSupport
|
@@ -22,11 +24,6 @@ module MerbAdmin
|
|
22
24
|
model.all(options)
|
23
25
|
end
|
24
26
|
|
25
|
-
def all_in(ids, options = {})
|
26
|
-
options[:conditions] = ["id IN (?)", ids]
|
27
|
-
model.all(options)
|
28
|
-
end
|
29
|
-
|
30
27
|
def paginated(options = {})
|
31
28
|
page = options.delete(:page) || 1
|
32
29
|
per_page = options.delete(:per_page) || MerbAdmin[:per_page]
|
@@ -169,6 +166,10 @@ module MerbAdmin
|
|
169
166
|
def clear_association(association)
|
170
167
|
association.clear
|
171
168
|
end
|
169
|
+
|
170
|
+
def reset
|
171
|
+
super
|
172
|
+
end
|
172
173
|
end
|
173
174
|
|
174
175
|
end
|
data/lib/datamapper_support.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-validations'
|
3
|
+
require 'dm-aggregates'
|
4
|
+
|
1
5
|
module MerbAdmin
|
2
6
|
class AbstractModel
|
3
7
|
module DatamapperSupport
|
@@ -20,11 +24,6 @@ module MerbAdmin
|
|
20
24
|
model.all(options)
|
21
25
|
end
|
22
26
|
|
23
|
-
def all_in(ids, options = {})
|
24
|
-
options[:id] = ids
|
25
|
-
model.all(options)
|
26
|
-
end
|
27
|
-
|
28
27
|
def paginated(options = {})
|
29
28
|
page = options.delete(:page) || 1
|
30
29
|
per_page = options.delete(:per_page) || MerbAdmin[:per_page]
|
@@ -157,6 +156,10 @@ module MerbAdmin
|
|
157
156
|
def clear_association(association)
|
158
157
|
association.clear
|
159
158
|
end
|
159
|
+
|
160
|
+
def reset
|
161
|
+
super
|
162
|
+
end
|
160
163
|
end
|
161
164
|
|
162
165
|
end
|
@@ -51,6 +51,27 @@ namespace :slices do
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
desc "Copies sample models, copies and runs sample migrations, and loads sample data"
|
55
|
+
task :sequel => ["sequel:copy_sample_models", "sequel:copy_sample_migrations", "sequel:migrate", "load_sample_data"]
|
56
|
+
namespace :sequel do
|
57
|
+
desc "Copies sample models into your app"
|
58
|
+
task :copy_sample_models do
|
59
|
+
copy_models(:sequel)
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "Copies sample migrations into your app"
|
63
|
+
task :copy_sample_migrations do
|
64
|
+
copy_migrations(:sequel)
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "Perform migration using migrations in schema/migrations"
|
68
|
+
task :migrate do
|
69
|
+
require 'sequel/extensions/migration'
|
70
|
+
Rake::Task["sequel:db:migrate"].reenable
|
71
|
+
Rake::Task["sequel:db:migrate"].invoke
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
54
75
|
desc "Loads sample data into your app"
|
55
76
|
task :load_sample_data do
|
56
77
|
load_data
|
@@ -63,13 +84,13 @@ private
|
|
63
84
|
|
64
85
|
def load_data
|
65
86
|
begin
|
66
|
-
require "mlb"
|
87
|
+
require "mlb"
|
67
88
|
rescue LoadError => e
|
68
89
|
puts "LoadError: #{e}"
|
69
90
|
puts "gem install mlb -s http://gemcutter.org"
|
70
91
|
return
|
71
92
|
end
|
72
|
-
|
93
|
+
|
73
94
|
puts "Loading current MLB leagues, divisions, teams, and players"
|
74
95
|
MLB.teams.each do |mlb_team|
|
75
96
|
unless league = MerbAdmin::AbstractModel.new("League").first(:conditions => ["name = ?", mlb_team.league])
|
data/lib/merb-admin.rb
CHANGED
@@ -23,7 +23,7 @@ if defined?(Merb::Plugins)
|
|
23
23
|
|
24
24
|
# Slice metadata
|
25
25
|
self.description = "MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data."
|
26
|
-
self.version = "0.
|
26
|
+
self.version = "0.6.0"
|
27
27
|
self.author = "Erik Michaels-Ober"
|
28
28
|
|
29
29
|
# Stub classes loaded hook - runs before LoadClasses BootLoader
|
@@ -0,0 +1,309 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
require 'sequel/extensions/pagination'
|
3
|
+
|
4
|
+
class Sequel::Model
|
5
|
+
=begin
|
6
|
+
# Intialize each column to the default value for new model objects
|
7
|
+
def after_initialize
|
8
|
+
super
|
9
|
+
model.columns.each do |x|
|
10
|
+
if !@values.include?(x) && db_schema[x][:allow_null]
|
11
|
+
send("#{x}=", db_schema[x][:ruby_default])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
=end
|
16
|
+
|
17
|
+
# Return an empty array for *_to_many association methods for new model objects
|
18
|
+
def _load_associated_objects(opts)
|
19
|
+
opts.returns_array? && new? ? [] : super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module MerbAdmin
|
24
|
+
class AbstractModel
|
25
|
+
module SequelSupport
|
26
|
+
def get(id)
|
27
|
+
model.first(:id => id).extend(InstanceMethods)
|
28
|
+
end
|
29
|
+
|
30
|
+
def count(options = {})
|
31
|
+
if options[:conditions] && !options[:conditions].empty?
|
32
|
+
# If options[:conditions] isn't cloned, Sequel eats the first condition!
|
33
|
+
model.where(options[:conditions].clone).count
|
34
|
+
else
|
35
|
+
model.count
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def first(options = {})
|
40
|
+
sort = options.delete(:sort) || :id
|
41
|
+
sort_order = options.delete(:sort_reverse) ? :desc : :asc
|
42
|
+
|
43
|
+
if options[:conditions] && !options[:conditions].empty?
|
44
|
+
# If options[:conditions] isn't cloned, Sequel eats the first condition!
|
45
|
+
model.order(sort.to_sym.send(sort_order)).first(options[:conditions].clone).extend(InstanceMethods)
|
46
|
+
else
|
47
|
+
model.order(sort.to_sym.send(sort_order)).first.extend(InstanceMethods)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def all(options = {})
|
52
|
+
offset = options.delete(:offset)
|
53
|
+
limit = options.delete(:limit)
|
54
|
+
|
55
|
+
sort = options.delete(:sort) || :id
|
56
|
+
sort_order = options.delete(:sort_reverse) ? :desc : :asc
|
57
|
+
|
58
|
+
if options[:conditions] && !options[:conditions].empty?
|
59
|
+
# If options[:conditions] isn't cloned, Sequel eats the first condition!
|
60
|
+
model.where(options[:conditions].clone).order(sort.to_sym.send(sort_order))
|
61
|
+
else
|
62
|
+
model.order(sort.to_sym.send(sort_order))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def paginated(options = {})
|
67
|
+
page = options.delete(:page) || 1
|
68
|
+
per_page = options.delete(:per_page) || MerbAdmin[:per_page]
|
69
|
+
page_count = (count(options).to_f / per_page).ceil
|
70
|
+
|
71
|
+
sort = options.delete(:sort) || :id
|
72
|
+
sort_order = options.delete(:sort_reverse) ? :desc : :asc
|
73
|
+
|
74
|
+
if options[:conditions] && !options[:conditions].empty?
|
75
|
+
# If options[:conditions] isn't cloned, Sequel eats the first condition!
|
76
|
+
[page_count, model.paginate(page.to_i, per_page).where(options[:conditions].clone).order(sort.to_sym.send(sort_order))]
|
77
|
+
else
|
78
|
+
[page_count, model.paginate(page.to_i, per_page).order(sort.to_sym.send(sort_order))]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def create(params = {})
|
83
|
+
model.create(params)
|
84
|
+
end
|
85
|
+
|
86
|
+
def new(params = {})
|
87
|
+
model.new(params).extend(InstanceMethods)
|
88
|
+
end
|
89
|
+
|
90
|
+
def destroy_all!
|
91
|
+
model.all.each do |object|
|
92
|
+
object.destroy
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def has_many_associations
|
97
|
+
associations.select do |association|
|
98
|
+
association[:type] == :has_many
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def has_one_associations
|
103
|
+
associations.select do |association|
|
104
|
+
association[:type] == :has_one
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def belongs_to_associations
|
109
|
+
associations.select do |association|
|
110
|
+
association[:type] == :belongs_to
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def associations
|
115
|
+
model.all_association_reflections.map do |association|
|
116
|
+
{
|
117
|
+
:name => association_name_lookup(association),
|
118
|
+
:pretty_name => association_pretty_name_lookup(association),
|
119
|
+
:type => association_type_lookup(association),
|
120
|
+
:parent_model => association_parent_model_lookup(association),
|
121
|
+
:parent_key => association_parent_key_lookup(association),
|
122
|
+
:child_model => association_child_model_lookup(association),
|
123
|
+
:child_key => association_child_key_lookup(association),
|
124
|
+
}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def properties
|
129
|
+
model.columns.map do |property|
|
130
|
+
{
|
131
|
+
:name => property,
|
132
|
+
:pretty_name => property.to_s.gsub(/_id$/, "").gsub("_", " ").capitalize,
|
133
|
+
:type => property_type_lookup(property),
|
134
|
+
:length => property_length_lookup(property),
|
135
|
+
:nullable? => model.db_schema[property][:allow_null],
|
136
|
+
:serial? => model.db_schema[property][:primary_key],
|
137
|
+
}
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def property_type_lookup(property)
|
144
|
+
case model.db_schema[property][:db_type]
|
145
|
+
when /\A(?:medium|small)?int(?:eger)?(?:\((?:\d+)\))?\z/io
|
146
|
+
:integer
|
147
|
+
when /\Atinyint(?:\((\d+)\))?\z/io
|
148
|
+
:boolean
|
149
|
+
when /\Abigint(?:\((?:\d+)\))?\z/io
|
150
|
+
:integer
|
151
|
+
when /\A(?:real|float|double(?: precision)?)\z/io
|
152
|
+
:float
|
153
|
+
when 'boolean'
|
154
|
+
:boolean
|
155
|
+
when /\A(?:(?:tiny|medium|long|n)?text|clob)\z/io
|
156
|
+
:text
|
157
|
+
when 'date'
|
158
|
+
:date
|
159
|
+
when /\A(?:small)?datetime\z/io
|
160
|
+
:datetime
|
161
|
+
when /\Atimestamp(?: with(?:out)? time zone)?\z/io
|
162
|
+
:datetime
|
163
|
+
when /\Atime(?: with(?:out)? time zone)?\z/io
|
164
|
+
:time
|
165
|
+
when /\An?char(?:acter)?(?:\((\d+)\))?\z/io
|
166
|
+
:string
|
167
|
+
when /\A(?:n?varchar|character varying|bpchar|string)(?:\((\d+)\))?\z/io
|
168
|
+
:string
|
169
|
+
when /\A(?:small)?money\z/io
|
170
|
+
:big_decimal
|
171
|
+
when /\A(?:decimal|numeric|number)(?:\((\d+)(?:,\s*(\d+))?\))?\z/io
|
172
|
+
:big_decimal
|
173
|
+
when 'year'
|
174
|
+
:integer
|
175
|
+
else
|
176
|
+
:string
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def property_length_lookup(property)
|
181
|
+
case model.db_schema[property][:db_type]
|
182
|
+
when /\An?char(?:acter)?(?:\((\d+)\))?\z/io
|
183
|
+
$1 ? $1.to_i : 255
|
184
|
+
when /\A(?:n?varchar|character varying|bpchar|string)(?:\((\d+)\))?\z/io
|
185
|
+
$1 ? $1.to_i : 255
|
186
|
+
else
|
187
|
+
nil
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def association_name_lookup(association)
|
192
|
+
case association[:type]
|
193
|
+
when :one_to_many
|
194
|
+
if association[:one_to_one]
|
195
|
+
association[:name].to_s.singularize.to_sym
|
196
|
+
else
|
197
|
+
association[:name]
|
198
|
+
end
|
199
|
+
when :many_to_one
|
200
|
+
association[:name]
|
201
|
+
else
|
202
|
+
raise "Unknown association type"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def association_pretty_name_lookup(association)
|
207
|
+
case association[:type]
|
208
|
+
when :one_to_many
|
209
|
+
if association[:one_to_one]
|
210
|
+
association[:name].to_s.singularize.gsub('_', ' ').capitalize
|
211
|
+
else
|
212
|
+
association[:name].to_s.gsub('_', ' ').capitalize
|
213
|
+
end
|
214
|
+
when :many_to_one
|
215
|
+
association[:name].to_s.gsub('_', ' ').capitalize
|
216
|
+
else
|
217
|
+
raise "Unknown association type"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def association_type_lookup(association)
|
222
|
+
case association[:type]
|
223
|
+
when :one_to_many
|
224
|
+
if association[:one_to_one]
|
225
|
+
:has_one
|
226
|
+
else
|
227
|
+
:has_many
|
228
|
+
end
|
229
|
+
when :many_to_one
|
230
|
+
:belongs_to
|
231
|
+
else
|
232
|
+
raise "Unknown association type"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def association_parent_model_lookup(association)
|
237
|
+
case association[:type]
|
238
|
+
when :one_to_many
|
239
|
+
association[:model]
|
240
|
+
when :many_to_one
|
241
|
+
Object.const_get(association[:class_name])
|
242
|
+
else
|
243
|
+
raise "Unknown association type"
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def association_parent_key_lookup(association)
|
248
|
+
[:id]
|
249
|
+
end
|
250
|
+
|
251
|
+
def association_child_model_lookup(association)
|
252
|
+
case association[:type]
|
253
|
+
when :one_to_many
|
254
|
+
Object.const_get(association[:class_name])
|
255
|
+
when :many_to_one
|
256
|
+
association[:model]
|
257
|
+
else
|
258
|
+
raise "Unknown association type"
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def association_child_key_lookup(association)
|
263
|
+
case association[:type]
|
264
|
+
when :one_to_many
|
265
|
+
association[:keys]
|
266
|
+
when :many_to_one
|
267
|
+
["#{association[:class_name].snake_case}_id".to_sym]
|
268
|
+
else
|
269
|
+
raise "Unknown association type"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
module InstanceMethods
|
274
|
+
def id
|
275
|
+
super
|
276
|
+
end
|
277
|
+
|
278
|
+
def save
|
279
|
+
super
|
280
|
+
end
|
281
|
+
|
282
|
+
def destroy
|
283
|
+
super
|
284
|
+
end
|
285
|
+
|
286
|
+
def update_attributes(attributes)
|
287
|
+
# NOTE: Not sure why calling update(attributes) raises
|
288
|
+
# Argument Error: wrong number of arguments (1 for 0)
|
289
|
+
# but this seems to work:
|
290
|
+
set(attributes)
|
291
|
+
save
|
292
|
+
end
|
293
|
+
|
294
|
+
def errors
|
295
|
+
super
|
296
|
+
end
|
297
|
+
|
298
|
+
def clear_association(association)
|
299
|
+
association.clear # FIXME!
|
300
|
+
end
|
301
|
+
|
302
|
+
def reset
|
303
|
+
super
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateDivisions < Sequel::Migration
|
2
|
+
def up
|
3
|
+
create_table(:divisions) do
|
4
|
+
primary_key(:id)
|
5
|
+
DateTime(:created_at)
|
6
|
+
DateTime(:updated_at)
|
7
|
+
foreign_key(:league_id, :table => :leagues)
|
8
|
+
String(:name, :limit => 50, :null => false)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def down
|
13
|
+
drop_table(:divisions)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateDrafts < Sequel::Migration
|
2
|
+
def up
|
3
|
+
create_table(:drafts) do
|
4
|
+
primary_key(:id)
|
5
|
+
DateTime(:created_at)
|
6
|
+
DateTime(:updated_at)
|
7
|
+
foreign_key(:player_id, :table => :players)
|
8
|
+
foreign_key(:team_id, :table => :teams)
|
9
|
+
Date(:date)
|
10
|
+
Integer(:round)
|
11
|
+
Integer(:pick)
|
12
|
+
Integer(:overall)
|
13
|
+
String(:college, :limit => 100)
|
14
|
+
String(:notes, :text=>true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def down
|
19
|
+
drop_table(:drafts)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateLeagues < Sequel::Migration
|
2
|
+
def up
|
3
|
+
create_table(:leagues) do
|
4
|
+
primary_key(:id)
|
5
|
+
DateTime(:created_at)
|
6
|
+
DateTime(:updated_at)
|
7
|
+
String(:name, :limit => 50, :null => false)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def down
|
12
|
+
drop_table(:leagues)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class CreatePlayers < Sequel::Migration
|
2
|
+
def up
|
3
|
+
create_table(:players) do
|
4
|
+
primary_key(:id)
|
5
|
+
DateTime(:created_at)
|
6
|
+
DateTime(:updated_at)
|
7
|
+
DateTime(:deleted_at)
|
8
|
+
foreign_key(:team_id, :table => :teams)
|
9
|
+
String(:name, :limit => 100, :null => false)
|
10
|
+
String(:position, :limit => 50)
|
11
|
+
Integer(:number, :null => false)
|
12
|
+
TrueClass(:retired, :default => false)
|
13
|
+
TrueClass(:injured, :default => false)
|
14
|
+
Date(:born_on)
|
15
|
+
String(:notes, :text=>true)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def down
|
20
|
+
drop_table(:players)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class CreateTeams < Sequel::Migration
|
2
|
+
def up
|
3
|
+
create_table(:teams) do
|
4
|
+
primary_key(:id)
|
5
|
+
DateTime(:created_at)
|
6
|
+
DateTime(:updated_at)
|
7
|
+
foreign_key(:league_id, :table => :leagues)
|
8
|
+
foreign_key(:division_id, :table => :divisions)
|
9
|
+
String(:name, :limit => 50, :null => false)
|
10
|
+
String(:logo_url, :limit => 255)
|
11
|
+
String(:manager, :limit => 100, :null => false)
|
12
|
+
String(:ballpark, :limit => 100)
|
13
|
+
String(:mascot, :limit => 100)
|
14
|
+
Integer(:founded)
|
15
|
+
Integer(:wins)
|
16
|
+
Integer(:losses)
|
17
|
+
Float(:win_percentage)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def down
|
22
|
+
drop_table(:teams)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Division < Sequel::Model
|
2
|
+
set_primary_key(:id)
|
3
|
+
plugin(:timestamps, :update_on_create => true)
|
4
|
+
plugin(:validation_helpers)
|
5
|
+
|
6
|
+
many_to_one(:league)
|
7
|
+
one_to_many(:teams)
|
8
|
+
|
9
|
+
self.raise_on_save_failure = false
|
10
|
+
self.raise_on_typecast_failure = false
|
11
|
+
def validate
|
12
|
+
validates_numeric(:league_id, :only_integer => true)
|
13
|
+
validates_presence(:name)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Draft < Sequel::Model
|
2
|
+
set_primary_key(:id)
|
3
|
+
plugin(:timestamps, :update_on_create => true)
|
4
|
+
plugin(:validation_helpers)
|
5
|
+
|
6
|
+
many_to_one(:team)
|
7
|
+
many_to_one(:player)
|
8
|
+
|
9
|
+
self.raise_on_save_failure = false
|
10
|
+
self.raise_on_typecast_failure = false
|
11
|
+
def validate
|
12
|
+
validates_numeric(:player_id, :only_integer => true, :allow_blank => true)
|
13
|
+
validates_numeric(:team_id, :only_integer => true, :allow_blank => true)
|
14
|
+
validates_presence(:date)
|
15
|
+
validates_numeric(:round, :only_integer => true)
|
16
|
+
validates_numeric(:pick, :only_integer => true)
|
17
|
+
validates_numeric(:overall, :only_integer => true)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class League < Sequel::Model
|
2
|
+
set_primary_key(:id)
|
3
|
+
plugin(:timestamps, :update_on_create => true)
|
4
|
+
plugin(:validation_helpers)
|
5
|
+
|
6
|
+
one_to_many(:divisions)
|
7
|
+
one_to_many(:teams)
|
8
|
+
|
9
|
+
self.raise_on_save_failure = false
|
10
|
+
self.raise_on_typecast_failure = false
|
11
|
+
def validate
|
12
|
+
validates_presence(:name)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Player < Sequel::Model
|
2
|
+
set_primary_key(:id)
|
3
|
+
plugin(:timestamps, :update_on_create => true)
|
4
|
+
plugin(:validation_helpers)
|
5
|
+
|
6
|
+
many_to_one(:team)
|
7
|
+
one_to_many(:drafts, :one_to_one => true)
|
8
|
+
|
9
|
+
self.raise_on_save_failure = false
|
10
|
+
self.raise_on_typecast_failure = false
|
11
|
+
def validate
|
12
|
+
validates_numeric(:number, :only_integer => true)
|
13
|
+
validates_unique(:number, :message => "There is already a player with that number on this team") do |dataset|
|
14
|
+
dataset.where("team_id = ?", team_id)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Team < Sequel::Model
|
2
|
+
set_primary_key(:id)
|
3
|
+
plugin(:timestamps, :update_on_create => true)
|
4
|
+
plugin(:validation_helpers)
|
5
|
+
|
6
|
+
many_to_one(:league)
|
7
|
+
many_to_one(:division)
|
8
|
+
one_to_many(:players)
|
9
|
+
|
10
|
+
self.raise_on_save_failure = false
|
11
|
+
self.raise_on_typecast_failure = false
|
12
|
+
def validate
|
13
|
+
validates_numeric(:league_id, :only_integer => true)
|
14
|
+
validates_numeric(:division_id, :only_integer => true)
|
15
|
+
validates_presence(:name)
|
16
|
+
validates_presence(:manager)
|
17
|
+
validates_numeric(:founded, :only_integer => true)
|
18
|
+
validates_numeric(:wins, :only_integer => true)
|
19
|
+
validates_numeric(:losses, :only_integer => true)
|
20
|
+
validates_numeric(:win_percentage)
|
21
|
+
end
|
22
|
+
end
|
data/spec/requests/main_spec.rb
CHANGED
@@ -449,6 +449,7 @@ describe "MerbAdmin" do
|
|
449
449
|
end
|
450
450
|
|
451
451
|
it "should be associated with the correct object" do
|
452
|
+
@draft.reload
|
452
453
|
MerbAdmin::AbstractModel.new("Player").first.draft.should == @draft
|
453
454
|
end
|
454
455
|
end
|
@@ -463,7 +464,9 @@ describe "MerbAdmin" do
|
|
463
464
|
end
|
464
465
|
|
465
466
|
it "should be associated with the correct objects" do
|
467
|
+
@teams[0].reload
|
466
468
|
MerbAdmin::AbstractModel.new("League").first.teams.should include(@teams[0])
|
469
|
+
@teams[1].reload
|
467
470
|
MerbAdmin::AbstractModel.new("League").first.teams.should include(@teams[1])
|
468
471
|
end
|
469
472
|
|
@@ -544,6 +547,7 @@ describe "MerbAdmin" do
|
|
544
547
|
end
|
545
548
|
|
546
549
|
it "should be associated with the correct object" do
|
550
|
+
@draft.reload
|
547
551
|
MerbAdmin::AbstractModel.new("Player").first.draft.should == @draft
|
548
552
|
end
|
549
553
|
end
|
@@ -558,7 +562,9 @@ describe "MerbAdmin" do
|
|
558
562
|
end
|
559
563
|
|
560
564
|
it "should be associated with the correct objects" do
|
565
|
+
@teams[0].reload
|
561
566
|
MerbAdmin::AbstractModel.new("League").first.teams.should include(@teams[0])
|
567
|
+
@teams[1].reload
|
562
568
|
MerbAdmin::AbstractModel.new("League").first.teams.should include(@teams[1])
|
563
569
|
end
|
564
570
|
|
data/spec/spec_helper.rb
CHANGED
@@ -64,6 +64,10 @@ module Merb
|
|
64
64
|
end
|
65
65
|
when :sequel
|
66
66
|
require 'sequel'
|
67
|
+
require 'sequel/extensions/blank'
|
68
|
+
require 'sequel/extensions/migration'
|
69
|
+
Sequel::Migrator.apply(Sequel.sqlite, File.join(File.dirname(__FILE__), "migrations", "sequel"))
|
70
|
+
require_models(orm)
|
67
71
|
else
|
68
72
|
raise "MerbAdmin does not support the #{orm} ORM"
|
69
73
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: merb-admin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erik Michaels-Ober
|
@@ -80,6 +80,7 @@ files:
|
|
80
80
|
- lib/merb-admin/slicetasks.rb
|
81
81
|
- lib/merb-admin/spectasks.rb
|
82
82
|
- lib/merb-admin.rb
|
83
|
+
- lib/sequel_support.rb
|
83
84
|
- public/images/arrow-down.gif
|
84
85
|
- public/images/arrow-up.gif
|
85
86
|
- public/images/changelist-bg.gif
|
@@ -158,6 +159,11 @@ files:
|
|
158
159
|
- spec/migrations/activerecord/003_create_leagues_migration.rb
|
159
160
|
- spec/migrations/activerecord/004_create_players_migration.rb
|
160
161
|
- spec/migrations/activerecord/005_create_teams_migration.rb
|
162
|
+
- spec/migrations/sequel/001_create_divisions_migration.rb
|
163
|
+
- spec/migrations/sequel/002_create_drafts_migration.rb
|
164
|
+
- spec/migrations/sequel/003_create_leagues_migration.rb
|
165
|
+
- spec/migrations/sequel/004_create_players_migration.rb
|
166
|
+
- spec/migrations/sequel/005_create_teams_migration.rb
|
161
167
|
- spec/models/activerecord/division.rb
|
162
168
|
- spec/models/activerecord/draft.rb
|
163
169
|
- spec/models/activerecord/league.rb
|
@@ -168,6 +174,11 @@ files:
|
|
168
174
|
- spec/models/datamapper/league.rb
|
169
175
|
- spec/models/datamapper/player.rb
|
170
176
|
- spec/models/datamapper/team.rb
|
177
|
+
- spec/models/sequel/division.rb
|
178
|
+
- spec/models/sequel/draft.rb
|
179
|
+
- spec/models/sequel/league.rb
|
180
|
+
- spec/models/sequel/player.rb
|
181
|
+
- spec/models/sequel/team.rb
|
171
182
|
- spec/requests/main_spec.rb
|
172
183
|
- spec/spec_helper.rb
|
173
184
|
has_rdoc: true
|