static_model 0.1.5 → 0.2.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 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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 FIXME full name
1
+ Copyright (c) 2008 Aaron Quint, Quirkey NYC, LLC
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/Manifest.txt CHANGED
@@ -1,22 +1,17 @@
1
1
  History.txt
2
2
  License.txt
3
3
  Manifest.txt
4
- README.txt
5
- Rakefile
6
- config/hoe.rb
7
- config/requirements.rb
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/version.rb
16
- setup.rb
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
@@ -1,6 +1,6 @@
1
1
  = static_model
2
2
 
3
- http://github.com/quirkey/static_model/
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
- Use like ActiveRecord::Base, except no database, just a YAML file. The YAML should contain an array of records.
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
- YAML
16
- activesupport >= 2.1.0
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,8 @@
1
+ Description:
2
+
3
+ Generates an empty StaticModel class/model
4
+
5
+ Usage:
6
+
7
+ ./script/generate static_model ModelName --data=config/data/ --lib=app/models/
8
+
@@ -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
@@ -0,0 +1,4 @@
1
+ class <%= class_name %> < StaticModel::Base
2
+ set_data_file File.join('<%= data_dir %>', '<%= table_name %>.yml')
3
+
4
+ end
@@ -0,0 +1,6 @@
1
+ ---
2
+ records:
3
+ - id: 1
4
+ name: One
5
+ - id: 2
6
+ name: Two
@@ -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
- records = YAML::load_file(data_file)
77
- @records = records ? records.dup.collect {|r| new(r) } : []
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.to_sym] = value
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(/=$/,'').to_sym
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 attributes[attribute_name]
162
+ return get_attribute(attribute_name)
138
163
  end
139
164
  end
140
165
  super
@@ -2,5 +2,6 @@ module StaticModel
2
2
  class Error < RuntimeError; end;
3
3
  class RecordNotFound < Error; end;
4
4
  class DataFileNotFound < Error; end;
5
+ class BadDataFile < Error; end;
5
6
  class BadOptions < Error; end;
6
7
  end
@@ -0,0 +1,15 @@
1
+ module StaticModel
2
+ module Scope
3
+
4
+ private
5
+ class << self
6
+ def with_scope
7
+
8
+ end
9
+
10
+ def scoped_conditions
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -1,8 +1,8 @@
1
1
  module StaticModel #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 1
5
- TINY = 5
4
+ MINOR = 2
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
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
 
@@ -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