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 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