collin (owner)

Revisions

gist: 192937 Download_button fork
public
Public Clone URL: git://gist.github.com/192937.git
Embed All Files: show embed
admin_asst.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
class AdminAssistantsController
  # 50/50 as to whether this will work the way I think it will.
  # I think it should result in a route like this: /:scope/admin/:id/edit/ (etc.)
  SuggestedRoute = %q{map.resources :admin, :path_prefix => "/:scope"}.freeze
  
  layout 'admin'
  respond_to :html
  
  before_filter :discover_admin
  def discover_admin scope
    @admin_assistant = AdminAssistant.get_or_initialize(scope)
  end
  
  delegate :scope, :admin_assistant
  
  index, show, new/create, edit/update, and destroy
  def index
    respond_with(@records = scope.all)
  end
 
  def show id
    respond_with(@record = scope.get(id))
  end
  
  def new id
    respond_with(@record = scope.new)
  end
  
  def create values
    respond_with(@record = scope.create(values))
  end
  
  def edit id
    respond_with(@record = scope.get(id))
  end
  
  def update id, values
    @record = scope.get(id)
    @record.update_attributes(values)
    respond_with(@record)
  end
  
  def destroy id
    @record = scope.get(id)
    @record.destroy
    respond_with(@record)
  end
end
 
class ActiveModel
  # TODO find a better way to reflect on all models
  def self.all
    Pathname.glob(Rails.root+'app/models/**/*.rb').map do |path|
      path.basename.gsub(".rb").constantize
    end
  end
end
 
class Model
  include DataMapper::Resource
  
  property :scope, String, :length => 255, :null => false, :key => true
 
  def self.get_or_create scope
    get(scope) or create(scope)
  end
 
  def self.create scope
    new.instance_eval { self.scope = scope; save }
  end
  
  def self.get scope
    super scope.to_s.underscore
  end
 
  def scope= value
    super value.to_s.underscore
  end
  
  def scope
    super.camelize.constantize
  end
 
  # ensure a record exists for each model at startup
  def self.generate_all_models
    ActiveModel.all.map {|klass| get_or_create klass.to_s.underscore }
  end
  generate_all_models
end
 
class AdminAssistant
  include DataMapper::Resource
  
  property :id, Serial
  
  belongs_to :model
  has n, :admin_assistant_actions
  has n, :admin_assistant_columns
  
  validates_is_unique :model
  
  def self.generate_all_admin_assistants
    Model.all.each do |model|
      assistant = find(:model => model).any? or create(:model => model)
      model.properties.each do |property|
        assistant.admin_assistant_columns.create(
          :label = > name.humanize
        )
      end
    end
  end
  generate_all_admin_assistants
end
 
class AdminAssistantColumn
  include DataMapper::Resource
  
  property :id, Serial
  property :true_label, String, :default => 'true', :null => false
  property :false_label, String, :default => 'false', :null => false
  property :label, String, :length => 255, :null => false
  property :include_blank, Boolean, :default => true, :null => false
  property :read_only, Boolean, :default => false, :null => false
  property :write_once, Boolean, :default => false, :null => false
  property :default, Object
  property :description, Text
  property :nilify_message, Text, :default => "set the value to nil", :null => false
  
  belongs_to :admin_assistant
  
  has n, :admin_assistant_column_polymorphic_types
  has n, :polymorpic_types, :class_name => 'Model', :through => :admin_assistant_column_polymorphic_types
end
 
class AdminAssistantColumnPolymorphicType
  include DataMapper::Resource
  
  property :id, Serial
  
  belongs_to :model
  belongs_to :admin_assistant_column
  
  validates_is_unique :model, :scope => [:admin_assistant_column]
end
 
class AdminAssistantAction
  include DataMapper::Resource
  
  property :id, Serial
  property :action, Discriminator
 
  belongs_to :admin_assistant
end
 
class AdminAssistantStateTransformingAction < AdminAssistantAction
end
 
class AdminAssistantDisplayAction < AdminAssistantAction
  class AdminAssistantDisplayColumnNotFromAssociatiedAdminAssistant < StandardError; end
  has n, :admin_assistant_columns, :through => Resource
  
  validates :admin_assistant_columns do
    admin_assistant_columns.each do |column|
      next if admin_assistant.admin_assistant_columns.include? column
      raise AdminAssistantDisplayColumnNotFromAssociatiedAdminAssistant
    end
  end
end
 
class AdminAssistantFormAction < AdminAssistantDisplayAction
end
 
class AdminAssistantDisplayColumn
  include DataMapper::Resource
end
 
class Index < AdminAssistantDisplayAction
end
 
class Search < AdminAssistantFormAction
end
 
class Show < AdminAssistantDisplayAction
end
 
class New < AdminAssistantFormAction
end
 
class Create < AdminAssistantStateTransformingAction
end
 
class Edit < AdminAssistantFormAction
end
 
class Update < AdminAssistantStateTransformingAction
end
 
class Destroy < AdminAssistantStateTransformingAction
end