stone 0.1.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/History.txt +3 -0
- data/License.txt +20 -0
- data/Manifest.txt +50 -0
- data/README.txt +52 -0
- data/Rakefile +22 -0
- data/bin/stone-gen +70 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +15 -0
- data/lib/stone/callbacks.rb +50 -0
- data/lib/stone/core_ext/string.rb +9 -0
- data/lib/stone/core_ext/symbol.rb +22 -0
- data/lib/stone/data_store.rb +80 -0
- data/lib/stone/query.rb +44 -0
- data/lib/stone/resource.rb +424 -0
- data/lib/stone/version.rb +9 -0
- data/lib/stone.rb +55 -0
- data/log/debug.log +0 -0
- data/sandbox_for_specs/datastore/.stone_metadata +2 -0
- data/sandbox_for_specs/datastore/authors/1.yml +12 -0
- data/sandbox_for_specs/datastore/authors/2.yml +12 -0
- data/sandbox_for_specs/datastore/authors/3.yml +12 -0
- data/sandbox_for_specs/datastore/authors/4.yml +12 -0
- data/sandbox_for_specs/datastore/authors/5.yml +12 -0
- data/sandbox_for_specs/datastore/posts/1.yml +8 -0
- data/sandbox_for_specs/datastore/posts/2.yml +8 -0
- data/sandbox_for_specs/sample_resources/author.rb +24 -0
- data/sandbox_for_specs/sample_resources/comment.rb +9 -0
- data/sandbox_for_specs/sample_resources/person.rb +6 -0
- data/sandbox_for_specs/sample_resources/post.rb +9 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +0 -0
- data/spec/callbacks_spec.rb +43 -0
- data/spec/query_spec.rb +19 -0
- data/spec/resource_spec.rb +190 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/stone_spec.rb +12 -0
- data/spec/string_spec.rb +16 -0
- data/spec/symbol_spec.rb +16 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/website/images/stone.png +0 -0
- data/website/index.html +392 -0
- data/website/index.txt +245 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +150 -0
- data/website/template.html.erb +48 -0
- metadata +143 -0
@@ -0,0 +1,424 @@
|
|
1
|
+
module Stone
|
2
|
+
|
3
|
+
# Adds the ability to persist any class it is included in
|
4
|
+
# === Example
|
5
|
+
#
|
6
|
+
# class Post
|
7
|
+
# include Stone::Resource
|
8
|
+
#
|
9
|
+
# field :body, String
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
module Resource
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def included(base)
|
16
|
+
rsrc_sym = base.to_s.make_key
|
17
|
+
|
18
|
+
@@callbacks ||= Callbacks.new
|
19
|
+
@@callbacks.register_klass(base)
|
20
|
+
|
21
|
+
@@store ||= DataStore.new
|
22
|
+
|
23
|
+
base.send(:extend, self)
|
24
|
+
base.send(:include, ::Validatable)
|
25
|
+
|
26
|
+
unless base.to_s.downcase =~ /spec::example::examplegroup::subclass_\d/
|
27
|
+
# allow object to be created with a hash of attributes...
|
28
|
+
# [] allows for obj[attribute] retrieval
|
29
|
+
# to_s allows for stupid Rails to work
|
30
|
+
base.class_eval <<-EOS, __FILE__, __LINE__
|
31
|
+
def initialize(hash = nil)
|
32
|
+
self.id = self.next_id_for_klass(self.class)
|
33
|
+
unless hash.blank?
|
34
|
+
hash.each_key do |k|
|
35
|
+
if hash[k].is_a? Hash
|
36
|
+
hash[k].each do |k,v|
|
37
|
+
self.send(k.to_s+"=",v)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
self.send(k.to_s+"=", hash[k])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
id
|
48
|
+
end
|
49
|
+
|
50
|
+
def [](sym)
|
51
|
+
self.send(sym)
|
52
|
+
end
|
53
|
+
EOS
|
54
|
+
end
|
55
|
+
|
56
|
+
unless @@store.resources.include?(rsrc_sym)
|
57
|
+
@@store.resources[rsrc_sym] = DataStore.load_data(rsrc_sym)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end # self
|
61
|
+
|
62
|
+
@@fields = {}
|
63
|
+
|
64
|
+
# Adds a given field to @@fields and inserts an accessor for that
|
65
|
+
# field into klass
|
66
|
+
# === Parameters
|
67
|
+
# +name+<String>::
|
68
|
+
#
|
69
|
+
def field(name, klass, arg = nil)
|
70
|
+
|
71
|
+
if arg && arg[:unique] == true
|
72
|
+
unique = true
|
73
|
+
else
|
74
|
+
unique = false
|
75
|
+
end
|
76
|
+
|
77
|
+
klass_sym = self.to_s.make_key
|
78
|
+
unless @@fields[klass_sym]
|
79
|
+
@@fields[klass_sym] = [{:name => name,
|
80
|
+
:klass => klass,
|
81
|
+
:unique => unique}]
|
82
|
+
else
|
83
|
+
@@fields[klass_sym] << {:name => name,
|
84
|
+
:klass => klass,
|
85
|
+
:unique => unique}
|
86
|
+
end
|
87
|
+
|
88
|
+
name = name.to_s
|
89
|
+
|
90
|
+
self.class_eval <<-EOS, __FILE__, __LINE__
|
91
|
+
def #{name}
|
92
|
+
@#{name}
|
93
|
+
end
|
94
|
+
|
95
|
+
def #{name}=(value)
|
96
|
+
@#{name} = value
|
97
|
+
end
|
98
|
+
EOS
|
99
|
+
end
|
100
|
+
|
101
|
+
def id=(value)
|
102
|
+
@id = value
|
103
|
+
end
|
104
|
+
|
105
|
+
def id
|
106
|
+
@id
|
107
|
+
end
|
108
|
+
|
109
|
+
# Registers the given method with the current instance of Callbacks. Upon
|
110
|
+
# activation (in this case, right before Resource.save is executed), the
|
111
|
+
# +meth+ given is called against the object being, in this case, saved.
|
112
|
+
# === Parameters
|
113
|
+
# +meth+:: The method to be registered
|
114
|
+
def before_save(meth)
|
115
|
+
@@callbacks.register(:before_save, meth, self)
|
116
|
+
end
|
117
|
+
|
118
|
+
# See before_save
|
119
|
+
def after_save(meth)
|
120
|
+
@@callbacks.register(:after_save, meth, self)
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# See before_save
|
125
|
+
def before_create(meth)
|
126
|
+
@@callbacks.register(:before_create, meth, self)
|
127
|
+
end
|
128
|
+
|
129
|
+
# See before_save
|
130
|
+
def after_create(meth)
|
131
|
+
@@callbacks.register(:after_create, meth, self)
|
132
|
+
end
|
133
|
+
|
134
|
+
# See before_save
|
135
|
+
def before_delete(meth)
|
136
|
+
@@callbacks.register(:before_delete, meth, self)
|
137
|
+
end
|
138
|
+
|
139
|
+
# See before_save
|
140
|
+
def after_delete(meth)
|
141
|
+
@@callbacks.register(:after_delete, meth, self)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Registers a has_many relationship for +resource+
|
145
|
+
# === Parameters
|
146
|
+
# +resource+::
|
147
|
+
# the resource of which this class has many
|
148
|
+
def has_many(resource, *args)
|
149
|
+
self.class_eval <<-EOS, __FILE__, __LINE__
|
150
|
+
def #{resource.to_s}
|
151
|
+
#{resource.to_s.singularize.titlecase}.all("#{self.to_s.downcase}_id".to_sym.equals => self.id)
|
152
|
+
end
|
153
|
+
EOS
|
154
|
+
end
|
155
|
+
|
156
|
+
def has_one(resource, *args)
|
157
|
+
field "#{resource.to_s}_id".to_sym, Fixnum
|
158
|
+
end
|
159
|
+
|
160
|
+
# Registers a belongs_to relationship for resource
|
161
|
+
# === Parameters
|
162
|
+
# +resource+ :: The resource to which this class belongs
|
163
|
+
def belongs_to(resource, *args)
|
164
|
+
field "#{resource.to_s}_id".to_sym, Fixnum
|
165
|
+
self.class_eval <<-EOS, __FILE__, __LINE__
|
166
|
+
def #{resource.to_s}
|
167
|
+
#{resource.to_s.titlecase}[self.#{resource.to_s}_id]
|
168
|
+
end
|
169
|
+
EOS
|
170
|
+
end
|
171
|
+
|
172
|
+
# TODO: implement this
|
173
|
+
def has_and_belongs_to_many(resource, *args)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Returns the first object matching +conditions+, or the first object
|
177
|
+
# if no conditions are specified
|
178
|
+
# === Parameters
|
179
|
+
# +conditions+::
|
180
|
+
# A hash representing one or more Ruby expressions
|
181
|
+
def first(conditions = nil)
|
182
|
+
unless conditions
|
183
|
+
return @@store.resources[self.to_s.make_key].first[1]
|
184
|
+
else
|
185
|
+
return find(conditions, self.to_s.make_key)[0]
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Returns all objects matching +conditions+, or all objects if no
|
190
|
+
# conditions are specified
|
191
|
+
# === Parameters
|
192
|
+
# +conditions+::
|
193
|
+
# A hash representing one or more Ruby expressions
|
194
|
+
def all(conditions = nil)
|
195
|
+
objs = []
|
196
|
+
unless conditions
|
197
|
+
@@store.resources[self.to_s.make_key].each do |o|
|
198
|
+
objs << o[1]
|
199
|
+
end
|
200
|
+
else
|
201
|
+
objs = find(conditions, self.to_s.make_key)
|
202
|
+
end
|
203
|
+
objs
|
204
|
+
end
|
205
|
+
|
206
|
+
# Synonymous for get
|
207
|
+
# === Parameters
|
208
|
+
# +id+:: id of the object to retrieve
|
209
|
+
def [](id)
|
210
|
+
raise "Expected Fixnum, got #{id.class} for #{self.to_s}[]" \
|
211
|
+
unless id.class == Fixnum || id.to_i
|
212
|
+
get(id)
|
213
|
+
end
|
214
|
+
|
215
|
+
def fields
|
216
|
+
@@fields
|
217
|
+
end
|
218
|
+
|
219
|
+
# Deletes the object with +id+ from the current DataStore instance and
|
220
|
+
# its corresponding yaml file
|
221
|
+
def delete(id)
|
222
|
+
fire(:before_delete)
|
223
|
+
DataStore.delete(id, self.to_s.downcase.pluralize)
|
224
|
+
@@store.resources[self.to_s.make_key].each_with_index do |o,i|
|
225
|
+
@@store.resources[self.to_s.make_key].delete_at(i) if o[0] == id
|
226
|
+
end
|
227
|
+
fire(:after_delete)
|
228
|
+
true
|
229
|
+
end
|
230
|
+
|
231
|
+
# Allow for retrieval of an object in the current DataStore instance by id
|
232
|
+
# === Parameters
|
233
|
+
# +id+:: id of the object to retrieve
|
234
|
+
def get(id)
|
235
|
+
id = id.to_i
|
236
|
+
raise "Expected Fixnum, got #{id.class} for #{self.to_s}.get" \
|
237
|
+
unless id.class == Fixnum
|
238
|
+
@@store.resources[self.to_s.make_key].each do |o|
|
239
|
+
return o[1] if o[0] == id
|
240
|
+
end
|
241
|
+
nil
|
242
|
+
end
|
243
|
+
|
244
|
+
# Puts the attribute changes in +hash+
|
245
|
+
# === Parameters
|
246
|
+
# +hash+:: the attributes to change
|
247
|
+
def update_attributes(hash)
|
248
|
+
hash.each_key do |k|
|
249
|
+
if hash[k].is_a? Hash
|
250
|
+
hash[k].each do |k,v|
|
251
|
+
self.send(k.to_s+"=",v)
|
252
|
+
end
|
253
|
+
else
|
254
|
+
self.send(k.to_s+"=", hash[k])
|
255
|
+
end
|
256
|
+
end
|
257
|
+
self.save
|
258
|
+
end
|
259
|
+
|
260
|
+
# Determine the next id number to use based on the last stored object's id
|
261
|
+
# of class +klass+
|
262
|
+
# === Parameters
|
263
|
+
# +klass+:: The class of the object to be saved
|
264
|
+
def next_id_for_klass(klass)
|
265
|
+
sym = klass.to_s.make_key
|
266
|
+
if @@store.resources.has_key?(sym) && !@@store.resources[sym].blank?
|
267
|
+
return @@store.resources[sym].last[0] + 1
|
268
|
+
else
|
269
|
+
return 1
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# Save an object to the current DataStore instance.
|
274
|
+
def save
|
275
|
+
return false unless self.fields_are_valid?
|
276
|
+
fire(:before_save)
|
277
|
+
return false unless self.valid?
|
278
|
+
sym = DataStore.determine_save_method(self, @@store)
|
279
|
+
self.class.send(sym, self)
|
280
|
+
fire(:after_save)
|
281
|
+
end
|
282
|
+
|
283
|
+
# Determines whether the field classes of a given object match the field
|
284
|
+
# class declarations
|
285
|
+
def fields_are_valid?
|
286
|
+
klass_sym = self.class.to_s.make_key
|
287
|
+
@@fields[klass_sym].each do |field|
|
288
|
+
unless self.send(field[:name]).class == field[:klass] || self.send(field[:name]) == nil || self.already_exists?
|
289
|
+
return false
|
290
|
+
end
|
291
|
+
if field[:unique] == true
|
292
|
+
return false if self.class.first(field[:name] => self.send(field[:name])) && !self.already_exists?
|
293
|
+
end
|
294
|
+
end
|
295
|
+
true
|
296
|
+
end
|
297
|
+
|
298
|
+
# Needed for Rails to work
|
299
|
+
def new_record?
|
300
|
+
!already_exists?
|
301
|
+
end
|
302
|
+
|
303
|
+
# Finds out if the object is already in the current DataStore instance
|
304
|
+
def already_exists?
|
305
|
+
DataStore.determine_save_method(self, @@store) == :put
|
306
|
+
end
|
307
|
+
|
308
|
+
private
|
309
|
+
|
310
|
+
# Fires the given callback in the current instance of Callbacks
|
311
|
+
# === Parameters
|
312
|
+
# +cb_sym+:: The symbol for the callback (e.g. :before_save)
|
313
|
+
def fire(cb_sym)
|
314
|
+
@@callbacks.fire(cb_sym, self)
|
315
|
+
true
|
316
|
+
end
|
317
|
+
|
318
|
+
# Creates a yaml file for +obj+ and adds +obj+ to the current DataStore
|
319
|
+
# instance
|
320
|
+
# === Parameters
|
321
|
+
# +obj+:: The object to be saved
|
322
|
+
def post(obj)
|
323
|
+
fire(:before_create)
|
324
|
+
obj.created_at = DateTime.now if field_declared?(:created_at,obj.class)
|
325
|
+
obj.updated_at = DateTime.now if field_declared?(:updated_at,obj.class)
|
326
|
+
DataStore.write_yaml(obj)
|
327
|
+
@@store.resources[obj.class.to_s.make_key] << [obj.id, obj]
|
328
|
+
fire(:after_create)
|
329
|
+
end
|
330
|
+
|
331
|
+
# Updates the yaml file for +obj+ and overwrites the old object in the
|
332
|
+
# the current DataStore instance
|
333
|
+
# === Parameters
|
334
|
+
#
|
335
|
+
def put(obj)
|
336
|
+
obj.updated_at = DateTime.now if field_declared?(:updated_at,obj.class)
|
337
|
+
DataStore.write_yaml(obj)
|
338
|
+
@@store.resources[obj.class.to_s.make_key].each do |o|
|
339
|
+
o[1] = obj if o[0] == obj.id
|
340
|
+
end
|
341
|
+
true
|
342
|
+
end
|
343
|
+
|
344
|
+
# Find an object according to +conditions+ provided
|
345
|
+
# === Parameters
|
346
|
+
# +conditions+:: A plain string representation of a set of conditions
|
347
|
+
# +key+::
|
348
|
+
# A symbol representing the class of objects to look for in the current
|
349
|
+
# DataStore instance
|
350
|
+
def find(conditions, key) #:doc:
|
351
|
+
objs = []
|
352
|
+
|
353
|
+
if conditions.is_a? Hash
|
354
|
+
unless conditions.to_a.flatten.map {|e| e.is_a? Query}.include?(true)
|
355
|
+
conds = conditions.to_a.flatten
|
356
|
+
@@store.resources[key].each do |o|
|
357
|
+
objs << o[1] if o[1].send(conds[0]) == conds[1]
|
358
|
+
end
|
359
|
+
else
|
360
|
+
parsed_conditions = parse_conditions(conditions)
|
361
|
+
@@store.resources[key].each do |o|
|
362
|
+
objs << o[1] if matches_conditions?(o[1], parsed_conditions)
|
363
|
+
end
|
364
|
+
end
|
365
|
+
else
|
366
|
+
raise "Resource.find expects a Hash, got a #{conditions.class}"
|
367
|
+
end
|
368
|
+
objs
|
369
|
+
end
|
370
|
+
|
371
|
+
# Checks the list of fields for a given +klass+ to see if +field+
|
372
|
+
# is included
|
373
|
+
# === Parameters
|
374
|
+
# +field+:: The field to look for
|
375
|
+
# +klass+:: The class to look in
|
376
|
+
def field_declared?(field,klass)
|
377
|
+
@@fields[klass.to_s.make_key].each do |f|
|
378
|
+
return true if f[:name] == field
|
379
|
+
end
|
380
|
+
false
|
381
|
+
end
|
382
|
+
|
383
|
+
# Executes and evaluates the expressions in +conds+ against
|
384
|
+
# the +obj+ provided, and then evaluates those results against
|
385
|
+
# the conditionals ("&&") in +conds+
|
386
|
+
# === Parameters
|
387
|
+
# +obj+:: The object to compare against
|
388
|
+
# +conds+::
|
389
|
+
# A set of expressions (name == 'nick') and their conditionals
|
390
|
+
# ('&&')
|
391
|
+
def matches_conditions?(obj, conds) #:doc:
|
392
|
+
tf_ary = []
|
393
|
+
conds.each_with_index do |cond,i|
|
394
|
+
# build an array like [true, "&&", false, "&&", true]
|
395
|
+
if i % 2 == 0
|
396
|
+
begin
|
397
|
+
bool = obj.instance_eval(cond)
|
398
|
+
bool = false unless bool
|
399
|
+
bool = true if bool.class == Fixnum
|
400
|
+
tf_ary << bool
|
401
|
+
rescue
|
402
|
+
tf_ary << false
|
403
|
+
end
|
404
|
+
else
|
405
|
+
tf_ary << cond
|
406
|
+
end
|
407
|
+
end
|
408
|
+
# evaluate the true/false array
|
409
|
+
eval(tf_ary.join)
|
410
|
+
end
|
411
|
+
|
412
|
+
# Turns conditions into a set of expressions that can be evaluated
|
413
|
+
def parse_conditions(hash)
|
414
|
+
conds = []
|
415
|
+
hash.each do |k,v|
|
416
|
+
conds << k.expression_for(v)
|
417
|
+
conds << "&&"
|
418
|
+
end
|
419
|
+
conds.pop
|
420
|
+
conds
|
421
|
+
end
|
422
|
+
end # Resource
|
423
|
+
|
424
|
+
end # Stone
|
data/lib/stone.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'validatable'
|
4
|
+
require 'english/inflect'
|
5
|
+
require 'facets'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
require File.expand_path(File.dirname(__FILE__) + '/stone/core_ext/string')
|
9
|
+
require File.expand_path(File.dirname(__FILE__) + '/stone/core_ext/symbol')
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + '/stone/query')
|
11
|
+
require File.expand_path(File.dirname(__FILE__) + '/stone/data_store')
|
12
|
+
require File.expand_path(File.dirname(__FILE__) + '/stone/callbacks')
|
13
|
+
require File.expand_path(File.dirname(__FILE__) + '/stone/resource')
|
14
|
+
|
15
|
+
STONE_ROOT = Dir.pwd
|
16
|
+
|
17
|
+
module Stone
|
18
|
+
class << self
|
19
|
+
|
20
|
+
# For spec stuff only
|
21
|
+
def empty_datastore
|
22
|
+
if File.exists? STONE_ROOT/"sandbox_for_specs/datastore"
|
23
|
+
FileUtils.rm_rf STONE_ROOT/"sandbox_for_specs/datastore"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates or updates a datastore at +path+
|
28
|
+
# === Parameters
|
29
|
+
# +path+<String>::
|
30
|
+
# Path to create or update datastore (usually an application's root)
|
31
|
+
# +resources+<Array>:: A list of resources that exist for the application
|
32
|
+
def start(path, resources, framework = nil)
|
33
|
+
DataStore.local_dir = path/"datastore"
|
34
|
+
|
35
|
+
# create the datastore dir unless it exists
|
36
|
+
FileUtils.mkdir(DataStore.local_dir) unless File.exists?(DataStore.local_dir)
|
37
|
+
|
38
|
+
# create a .stone_metadata that contains the resource locations
|
39
|
+
# for Stone::Utilities to use
|
40
|
+
File.open(DataStore.local_dir/".stone_metadata", "w") do |out|
|
41
|
+
YAML.dump({:rsrc_path => File.dirname(resources.first)}, out)
|
42
|
+
end unless File.exists?(DataStore.local_dir/".stone_metadata")
|
43
|
+
|
44
|
+
# load each resource unless a framework has already done it
|
45
|
+
resources.each do |resource|
|
46
|
+
require resource unless framework == :merb || framework == :rails
|
47
|
+
name = File.basename(resource).gsub(".rb", "").pluralize
|
48
|
+
unless File.exists? DataStore.local_dir/name
|
49
|
+
FileUtils.mkdir(DataStore.local_dir/name)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end # self
|
55
|
+
end # Stone
|
data/log/debug.log
ADDED
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
--- !ruby/object:Author
|
2
|
+
created_at: 2008-04-14T22:09:02-07:00
|
3
|
+
email: nick@cladby.com
|
4
|
+
errors: !ruby/object:Validatable::Errors
|
5
|
+
errors: {}
|
6
|
+
|
7
|
+
favorite_number: 27
|
8
|
+
id: 1
|
9
|
+
name: Nick DeMonner
|
10
|
+
times_validated_hash:
|
11
|
+
Author/Validatable::ValidatesPresenceOf/email: 4
|
12
|
+
Author/Validatable::ValidatesPresenceOf/name: 4
|
@@ -0,0 +1,12 @@
|
|
1
|
+
--- !ruby/object:Author
|
2
|
+
created_at: 2008-04-14T22:09:02-07:00
|
3
|
+
email: heyo@something.com
|
4
|
+
errors: !ruby/object:Validatable::Errors
|
5
|
+
errors: {}
|
6
|
+
|
7
|
+
favorite_number: 47
|
8
|
+
id: 2
|
9
|
+
name: Mike McMichaels
|
10
|
+
times_validated_hash:
|
11
|
+
Author/Validatable::ValidatesPresenceOf/email: 1
|
12
|
+
Author/Validatable::ValidatesPresenceOf/name: 1
|
@@ -0,0 +1,12 @@
|
|
1
|
+
--- !ruby/object:Author
|
2
|
+
created_at: 2008-04-14T22:09:02-07:00
|
3
|
+
email: weyo@something.com
|
4
|
+
errors: !ruby/object:Validatable::Errors
|
5
|
+
errors: {}
|
6
|
+
|
7
|
+
favorite_number: 30
|
8
|
+
id: 3
|
9
|
+
name: Mary Poppins
|
10
|
+
times_validated_hash:
|
11
|
+
Author/Validatable::ValidatesPresenceOf/email: 1
|
12
|
+
Author/Validatable::ValidatesPresenceOf/name: 1
|
@@ -0,0 +1,12 @@
|
|
1
|
+
--- !ruby/object:Author
|
2
|
+
created_at: 2008-04-14T22:09:02-07:00
|
3
|
+
email: nick@gmail.com
|
4
|
+
errors: !ruby/object:Validatable::Errors
|
5
|
+
errors: {}
|
6
|
+
|
7
|
+
favorite_number: 49
|
8
|
+
id: 4
|
9
|
+
name: Nick Hicklesby
|
10
|
+
times_validated_hash:
|
11
|
+
Author/Validatable::ValidatesPresenceOf/email: 1
|
12
|
+
Author/Validatable::ValidatesPresenceOf/name: 1
|
@@ -0,0 +1,12 @@
|
|
1
|
+
--- !ruby/object:Author
|
2
|
+
created_at: 2008-04-14T22:09:02-07:00
|
3
|
+
email: chariot_guy@hotmail.com
|
4
|
+
errors: !ruby/object:Validatable::Errors
|
5
|
+
errors: {}
|
6
|
+
|
7
|
+
favorite_number: 40
|
8
|
+
id: 5
|
9
|
+
name: Ben Hurr
|
10
|
+
times_validated_hash:
|
11
|
+
Author/Validatable::ValidatesPresenceOf/email: 1
|
12
|
+
Author/Validatable::ValidatesPresenceOf/name: 1
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Author #:nodoc:
|
2
|
+
include Stone::Resource
|
3
|
+
|
4
|
+
field :name, String
|
5
|
+
field :email, String, :unique => true
|
6
|
+
field :favorite_number, Fixnum
|
7
|
+
field :created_at, DateTime
|
8
|
+
|
9
|
+
validates_presence_of :name, :email
|
10
|
+
|
11
|
+
before_save :cap_name
|
12
|
+
before_save :give_random_number
|
13
|
+
|
14
|
+
has_many :posts
|
15
|
+
has_many :comments
|
16
|
+
|
17
|
+
def cap_name
|
18
|
+
self.name = self.name.titlecase
|
19
|
+
end
|
20
|
+
|
21
|
+
def give_random_number
|
22
|
+
self.favorite_number = rand(50)+1 unless self.favorite_number
|
23
|
+
end
|
24
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/stone.rb'}"
|
9
|
+
puts "Loading stone gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|