static_model 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/License.txt +1 -1
- data/Manifest.txt +9 -14
- data/{README.txt → README.rdoc} +12 -4
- data/generators/static_model/USAGE +8 -0
- data/generators/static_model/static_model_generator.rb +57 -0
- data/generators/static_model/templates/model.rb.erb +4 -0
- data/generators/static_model/templates/models.yml.erb +6 -0
- data/lib/static_model/base.rb +33 -8
- data/lib/static_model/errors.rb +1 -0
- data/lib/static_model/scope.rb +15 -0
- data/lib/static_model/version.rb +2 -2
- data/lib/static_model.rb +2 -0
- data/test/test_generator_helper.rb +29 -0
- data/test/test_helper.rb +8 -3
- data/test/test_static_model.rb +43 -2
- data/test/test_static_model_generator.rb +48 -0
- metadata +26 -19
- data/Rakefile +0 -4
- data/config/hoe.rb +0 -73
- data/config/requirements.rb +0 -15
- data/setup.rb +0 -1585
- data/test/authors.yml +0 -10
- data/test/books.yml +0 -22
- data/test/publishers.yml +0 -5
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.2.0 2008-10-27
|
2
|
+
|
3
|
+
* 2 major enhancements
|
4
|
+
|
5
|
+
* StaticModel generator
|
6
|
+
* 'class_attributes' and ability to set default for record attributes
|
7
|
+
* Real documentation on the website: http://quirkey.rubyforge.org/static_model
|
8
|
+
|
1
9
|
== 0.1.5 2008-09-18
|
2
10
|
|
3
11
|
* 1 minor enhancement
|
data/License.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -1,22 +1,17 @@
|
|
1
1
|
History.txt
|
2
2
|
License.txt
|
3
3
|
Manifest.txt
|
4
|
-
README.
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
README.rdoc
|
5
|
+
generators/static_model/USAGE
|
6
|
+
generators/static_model/static_model_generator.rb
|
7
|
+
generators/static_model/templates/model.rb.erb
|
8
|
+
generators/static_model/templates/models.yml.erb
|
8
9
|
lib/static_model.rb
|
9
|
-
lib/static_model/base.rb
|
10
|
-
lib/static_model/associations.rb
|
11
10
|
lib/static_model/active_record.rb
|
11
|
+
lib/static_model/associations.rb
|
12
|
+
lib/static_model/base.rb
|
12
13
|
lib/static_model/comparable.rb
|
13
14
|
lib/static_model/errors.rb
|
14
15
|
lib/static_model/rails.rb
|
15
|
-
lib/static_model/
|
16
|
-
|
17
|
-
test/books.yml
|
18
|
-
test/authors.yml
|
19
|
-
test/publishers.yml
|
20
|
-
test/test_helper.rb
|
21
|
-
test/test_static_model.rb
|
22
|
-
test/test_static_model_associations.rb
|
16
|
+
lib/static_model/scope.rb
|
17
|
+
lib/static_model/version.rb
|
data/{README.txt → README.rdoc}
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
= static_model
|
2
2
|
|
3
|
-
http://
|
3
|
+
http://quirkey.rubyforge.org/static_model/
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
@@ -8,16 +8,24 @@ ActiveRecord like functionalities for reading from YAML with a simple class impl
|
|
8
8
|
|
9
9
|
== SYNOPSIS:
|
10
10
|
|
11
|
-
|
11
|
+
Use like ActiveRecord::Base, except no database, just a YAML file. The YAML should contain an array of records.
|
12
|
+
|
13
|
+
For usage and setup check out the project's site:
|
14
|
+
|
15
|
+
http://quirkey.rubyforge.org/static_model/
|
12
16
|
|
13
17
|
== REQUIREMENTS:
|
14
18
|
|
15
|
-
|
16
|
-
|
19
|
+
YAML
|
20
|
+
activesupport >= 2.1.0
|
17
21
|
|
18
22
|
== INSTALL:
|
19
23
|
|
20
24
|
sudo gem install static_model
|
25
|
+
|
26
|
+
The source is at github:
|
27
|
+
|
28
|
+
http://github.com/quirkey/static_model/
|
21
29
|
|
22
30
|
== LICENSE:
|
23
31
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class StaticModelGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
default_options :author => nil
|
4
|
+
|
5
|
+
attr_reader :name, :lib_dir, :data_dir
|
6
|
+
|
7
|
+
def initialize(runtime_args, runtime_options = {})
|
8
|
+
super
|
9
|
+
usage if args.empty?
|
10
|
+
@name = args.shift
|
11
|
+
extract_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def manifest
|
15
|
+
record do |m|
|
16
|
+
# Ensure appropriate folder(s) exists
|
17
|
+
m.directory data_dir
|
18
|
+
m.directory lib_dir
|
19
|
+
m.template 'model.rb.erb', File.join(lib_dir, name.underscore + ".rb")
|
20
|
+
m.template 'models.yml.erb', File.join(data_dir, table_name + ".yml")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
def banner
|
26
|
+
<<-EOS
|
27
|
+
Creates a ...
|
28
|
+
|
29
|
+
USAGE: #{$0} #{spec.name} ModelName
|
30
|
+
EOS
|
31
|
+
end
|
32
|
+
|
33
|
+
def class_name
|
34
|
+
@name.classify
|
35
|
+
end
|
36
|
+
|
37
|
+
def table_name
|
38
|
+
@name.tableize
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_options!(opts)
|
42
|
+
# opts.separator ''
|
43
|
+
# opts.separator 'Options:'
|
44
|
+
# For each option below, place the default
|
45
|
+
# at the top of the file next to "default_options"
|
46
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
47
|
+
# "Some comment about this option",
|
48
|
+
# "Default: none") { |options[:author]| }
|
49
|
+
opts.on("-l", "--lib=your/path/", String, "Put the model.rb in a specific lib dir (default = app/models/)") {|o| options[:lib_dir] = o }
|
50
|
+
opts.on("-d", "--data=your/path/", String, "Put the models.yml data file in a specific data dir (default = config/data/)") {|o| options[:data_dir] = o }
|
51
|
+
end
|
52
|
+
|
53
|
+
def extract_options
|
54
|
+
@lib_dir = options[:lib_dir] || File.join('app', 'models')
|
55
|
+
@data_dir = options[:data_dir] || File.join('config', 'data')
|
56
|
+
end
|
57
|
+
end
|
data/lib/static_model/base.rb
CHANGED
@@ -7,7 +7,8 @@ module StaticModel
|
|
7
7
|
@@load_path = File.join('config', 'data')
|
8
8
|
|
9
9
|
attr_reader :id
|
10
|
-
|
10
|
+
|
11
|
+
|
11
12
|
def initialize(attribute_hash = {})
|
12
13
|
raise(StaticModel::BadOptions, "Initializing a model is done with a Hash {} given #{attribute_hash.inspect}") unless attribute_hash.is_a?(Hash)
|
13
14
|
@id = attribute_hash.delete('id') || attribute_hash.delete(:id) || (self.class.count + 1)
|
@@ -19,7 +20,7 @@ module StaticModel
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def attributes
|
22
|
-
@attributes ||=
|
23
|
+
@attributes ||= HashWithIndifferentAccess.new
|
23
24
|
end
|
24
25
|
|
25
26
|
def attributes=(attribute_hash)
|
@@ -27,7 +28,7 @@ module StaticModel
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def attribute_names
|
30
|
-
attributes.keys
|
31
|
+
(attributes.keys | self.class.class_attributes.keys).collect {|k| k.to_s }
|
31
32
|
end
|
32
33
|
|
33
34
|
class << self
|
@@ -73,9 +74,18 @@ module StaticModel
|
|
73
74
|
def load(reload = false)
|
74
75
|
return if loaded? && !reload
|
75
76
|
raise(StaticModel::DataFileNotFound, "You must set a data file to load from") unless File.readable?(data_file)
|
76
|
-
|
77
|
-
|
77
|
+
data = YAML::load_file(data_file)
|
78
|
+
records = []
|
79
|
+
if data.is_a?(Hash) && data.has_key?('records')
|
80
|
+
records = data.delete('records')
|
81
|
+
@class_attributes = HashWithIndifferentAccess.new(data)
|
82
|
+
elsif data.is_a?(Array)
|
83
|
+
records = data
|
84
|
+
end
|
85
|
+
@records = records && !records.empty? ? records.dup.collect {|r| new(r) } : []
|
78
86
|
@loaded = true
|
87
|
+
# rescue
|
88
|
+
# raise(StaticModel::BadDataFile, "The data file you specified '#{data_file}' was not in a readable format.")
|
79
89
|
end
|
80
90
|
|
81
91
|
def loaded?
|
@@ -98,6 +108,15 @@ module StaticModel
|
|
98
108
|
records.length
|
99
109
|
end
|
100
110
|
|
111
|
+
def class_attributes
|
112
|
+
load
|
113
|
+
@class_attributes ||= {}
|
114
|
+
end
|
115
|
+
|
116
|
+
def class_attribute(name)
|
117
|
+
class_attributes[name]
|
118
|
+
end
|
119
|
+
|
101
120
|
def records
|
102
121
|
load
|
103
122
|
@records
|
@@ -115,6 +134,8 @@ module StaticModel
|
|
115
134
|
attribute_name = meth_name.gsub(/^find_(all_by|first_by|by)_/, '')
|
116
135
|
finder = meth_name.gsub(/_#{attribute_name}/, '')
|
117
136
|
return self.send(finder, attribute_name, *args)
|
137
|
+
elsif class_attributes.has_key? meth_name
|
138
|
+
return class_attributes[meth_name]
|
118
139
|
end
|
119
140
|
super
|
120
141
|
end
|
@@ -122,19 +143,23 @@ module StaticModel
|
|
122
143
|
|
123
144
|
protected
|
124
145
|
def set_attribute(name, value)
|
125
|
-
self.attributes[name
|
146
|
+
self.attributes[name] = value
|
147
|
+
end
|
148
|
+
|
149
|
+
def get_attribute(name)
|
150
|
+
attributes.has_key?(name) ? attributes[name] : self.class.class_attribute(name)
|
126
151
|
end
|
127
152
|
|
128
153
|
private
|
129
154
|
def method_missing(meth, *args)
|
130
|
-
attribute_name = meth.to_s.gsub(/=$/,'')
|
155
|
+
attribute_name = meth.to_s.gsub(/=$/,'')
|
131
156
|
if attribute_names.include?(attribute_name)
|
132
157
|
if meth.to_s =~ /=$/
|
133
158
|
# set
|
134
159
|
return set_attribute(attribute_name, args[0])
|
135
160
|
else
|
136
161
|
# get
|
137
|
-
return
|
162
|
+
return get_attribute(attribute_name)
|
138
163
|
end
|
139
164
|
end
|
140
165
|
super
|
data/lib/static_model/errors.rb
CHANGED
data/lib/static_model/version.rb
CHANGED
data/lib/static_model.rb
CHANGED
@@ -4,8 +4,10 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
4
4
|
require 'yaml'
|
5
5
|
|
6
6
|
require 'active_support/inflector'
|
7
|
+
require 'active_support/core_ext/hash'
|
7
8
|
require 'active_support/core_ext/string'
|
8
9
|
|
10
|
+
|
9
11
|
require 'static_model/errors'
|
10
12
|
require 'static_model/associations'
|
11
13
|
require 'static_model/active_record'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
begin
|
2
|
+
require File.dirname(__FILE__) + '/test_helper'
|
3
|
+
rescue LoadError
|
4
|
+
require 'test/unit'
|
5
|
+
end
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
# Must set before requiring generator libs.
|
9
|
+
TMP_ROOT = File.dirname(__FILE__) + "/tmp" unless defined?(TMP_ROOT)
|
10
|
+
PROJECT_NAME = "myproject" unless defined?(PROJECT_NAME)
|
11
|
+
app_root = File.join(TMP_ROOT, PROJECT_NAME)
|
12
|
+
if defined?(APP_ROOT)
|
13
|
+
APP_ROOT.replace(app_root)
|
14
|
+
else
|
15
|
+
APP_ROOT = app_root
|
16
|
+
end
|
17
|
+
if defined?(RAILS_ROOT)
|
18
|
+
RAILS_ROOT.replace(app_root)
|
19
|
+
else
|
20
|
+
RAILS_ROOT = app_root
|
21
|
+
end
|
22
|
+
|
23
|
+
begin
|
24
|
+
require 'rubigen'
|
25
|
+
rescue LoadError
|
26
|
+
require 'rubygems'
|
27
|
+
require 'rubigen'
|
28
|
+
end
|
29
|
+
require 'rubigen/helpers/generator_test_helper'
|
data/test/test_helper.rb
CHANGED
@@ -6,7 +6,7 @@ require 'mocha'
|
|
6
6
|
require File.dirname(__FILE__) + '/../lib/static_model'
|
7
7
|
|
8
8
|
class Book < StaticModel::Base
|
9
|
-
set_data_file File.join(File.dirname(__FILE__), 'books.yml')
|
9
|
+
set_data_file File.join(File.dirname(__FILE__), 'data', 'books.yml')
|
10
10
|
end
|
11
11
|
|
12
12
|
unless defined?(ActiveRecord::Base)
|
@@ -22,18 +22,23 @@ class Article < ActiveRecord::Base
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class Publisher < StaticModel::Base
|
25
|
-
set_data_file File.join(File.dirname(__FILE__), 'publishers.yml')
|
25
|
+
set_data_file File.join(File.dirname(__FILE__), 'data', 'publishers.yml')
|
26
26
|
|
27
27
|
has_many :authors
|
28
28
|
end
|
29
29
|
|
30
30
|
class Author < StaticModel::Base
|
31
|
-
set_data_file File.join(File.dirname(__FILE__), 'authors.yml')
|
31
|
+
set_data_file File.join(File.dirname(__FILE__), 'data','authors.yml')
|
32
32
|
has_many :books
|
33
33
|
has_many :articles
|
34
34
|
belongs_to :publisher
|
35
35
|
end
|
36
36
|
|
37
|
+
class Page < StaticModel::Base
|
38
|
+
set_data_file File.join(File.dirname(__FILE__), 'data', 'pages.yml')
|
39
|
+
|
40
|
+
end
|
41
|
+
|
37
42
|
|
38
43
|
|
39
44
|
|
data/test/test_static_model.rb
CHANGED
@@ -66,7 +66,7 @@ class TestStaticModel < Test::Unit::TestCase
|
|
66
66
|
@book = Book.find(1)
|
67
67
|
@author = Author.find(1)
|
68
68
|
@original_data_file = Book.data_file
|
69
|
-
@data_file = File.join(File.dirname(__FILE__), 'authors.yml')
|
69
|
+
@data_file = File.join(File.dirname(__FILE__), 'data', 'authors.yml')
|
70
70
|
Book.set_data_file @data_file
|
71
71
|
@new_book = Book.find(1)
|
72
72
|
end
|
@@ -176,7 +176,7 @@ class TestStaticModel < Test::Unit::TestCase
|
|
176
176
|
context "with an empty data file" do
|
177
177
|
setup do
|
178
178
|
@original_data_file = Book.data_file
|
179
|
-
@data_file = File.join(File.dirname(__FILE__), 'empty.yml')
|
179
|
+
@data_file = File.join(File.dirname(__FILE__), 'data', 'empty.yml')
|
180
180
|
Book.set_data_file @data_file
|
181
181
|
end
|
182
182
|
|
@@ -295,6 +295,47 @@ class TestStaticModel < Test::Unit::TestCase
|
|
295
295
|
assert_equal Book.all.length, Book.count
|
296
296
|
end
|
297
297
|
end
|
298
|
+
|
299
|
+
context "with a class with yaml class vars" do
|
300
|
+
setup do
|
301
|
+
@pages = Page.all
|
302
|
+
end
|
303
|
+
|
304
|
+
should "load :records into @records" do
|
305
|
+
assert_set_of Page, @pages
|
306
|
+
assert Page.loaded?
|
307
|
+
end
|
308
|
+
|
309
|
+
should "give access to top level attributes as class methods" do
|
310
|
+
assert_equal 'http://www.quirkey.com', Page.url
|
311
|
+
assert_equal 'The Best Ever', Page.title
|
312
|
+
end
|
313
|
+
|
314
|
+
should "return a hash for class attribute" do
|
315
|
+
assert Page.settings.is_a?(Hash)
|
316
|
+
assert_equal 'test', Page.settings['username']
|
317
|
+
end
|
318
|
+
|
319
|
+
should "have class attributes appear as record accessor defaults if none exist" do
|
320
|
+
assert_equal 'http://www.quirkey.com', Page[1].url
|
321
|
+
end
|
322
|
+
|
323
|
+
should "not overwrite record specific methods" do
|
324
|
+
assert_equal 'http://github.com', Page[2].url
|
325
|
+
end
|
326
|
+
|
327
|
+
context "class_attributes" do
|
328
|
+
setup do
|
329
|
+
@attributes = Page.class_attributes
|
330
|
+
end
|
331
|
+
|
332
|
+
should "return a hash of all top level settings" do
|
333
|
+
assert @attributes.is_a?(Hash)
|
334
|
+
assert_equal 3, @attributes.length
|
335
|
+
assert_equal 'http://www.quirkey.com', @attributes['url']
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
298
339
|
|
299
340
|
end
|
300
341
|
end
|