merb-admin 0.5.7 → 0.6.0
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/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
|