minimodel 0.2.0 → 2.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e3103b9d7124f91936f1ad70da337f999f230a4463a6a7933f7566d5997837ad
4
+ data.tar.gz: d4f57fd1224b32b6ab488b8365457cef1263e119252f38287eb02760c194ba28
5
+ SHA512:
6
+ metadata.gz: 13d65ca6e41549bb006fd737b3592c0095f03fbea9badf9f2512611cdaf3860e06579e77d51107da7adc71506ddd81fbbe95ff1e892749ba98f50b3ebad1494d
7
+ data.tar.gz: ef6cbce222f3fa1ebf1e9088e32a824a92ab4250cf6e73bacd880a56910d6d43706f94cb1b99899eac58e507527c1f098bf3ef450de18acd5962a31e14641bf9
@@ -0,0 +1,33 @@
1
+ # 2.0.1
2
+
3
+ * Added CHANGES.md to gem files
4
+
5
+ * Added metadata to gemspec
6
+
7
+ # 2.0.0
8
+
9
+ * Added MiniModel.options method for use with options_for_select
10
+
11
+ * Dropped Ruby 1.8.7 compatibility
12
+
13
+ # 1.0.0
14
+
15
+ * Ruby 1.8.7 compatibility
16
+
17
+ # 0.4.0
18
+
19
+ * Added MiniModel.keys method
20
+
21
+ # 0.3.0
22
+
23
+ * Changed MiniModel.find method to raise exception for non-existent keys
24
+
25
+ # 0.2.0
26
+
27
+ * Added MiniModel#to_json method
28
+
29
+ * Added MiniModel#read_attribute method
30
+
31
+ # 0.1.0
32
+
33
+ * First version!
@@ -0,0 +1,4 @@
1
+ Copyright (c) 2011-2020 TIMCRAFT
2
+
3
+ This is an Open Source project licensed under the terms of the LGPLv3 license.
4
+ Please see <http://www.gnu.org/licenses/lgpl-3.0.html> for license text.
@@ -0,0 +1,45 @@
1
+ # minimodel
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/minimodel.svg)](https://badge.fury.io/rb/minimodel) [![Build Status](https://api.travis-ci.org/timcraft/minimodel.svg?branch=master)](https://travis-ci.org/timcraft/minimodel)
4
+
5
+
6
+ A little Ruby library for defining little models.
7
+
8
+
9
+ ## Installation
10
+
11
+ $ gem install minimodel
12
+
13
+
14
+ ## Motivation
15
+
16
+ Many apps use small "read only" datasets that can easily be held in memory,
17
+ for example: currency data, country data, colour data, advertising banners,
18
+ options for select boxes, payment plans etc. Sometimes it's useful to model
19
+ this data without using a database, and that's what minimodel is for.
20
+
21
+
22
+ ## Example
23
+
24
+ Here's how you could implement a currency model using minimodel:
25
+
26
+ ```ruby
27
+ require 'minimodel'
28
+
29
+ class Currency < MiniModel
30
+ indexed_by :code
31
+
32
+ insert code: 'EUR', name: 'Euro'
33
+ insert code: 'GBP', name: 'Pound sterling'
34
+ insert code: 'USD', name: 'United States dollar'
35
+ end
36
+ ```
37
+
38
+ The Currency class will respond to `#count` (returning the total number of
39
+ currencies), `#all` (returning an array of currency objects), and `#find`
40
+ (to lookup a specific currency by its code). Similar to ActiveRecord.
41
+
42
+ There's also a `load_from` class method which will load data from a YAML
43
+ file; useful for when you'd rather store the raw data outside of the class.
44
+
45
+ Take a look at `spec/*_spec.rb` for more examples. Have fun!
@@ -26,7 +26,7 @@ class MiniModel
26
26
  end
27
27
 
28
28
  def method_missing(symbol, *args, &block)
29
- if @attributes.has_key?(symbol) && args.empty? && block.nil?
29
+ if @attributes.key?(symbol) && args.empty? && block.nil?
30
30
  return @attributes[symbol]
31
31
  else
32
32
  super symbol, *args, &block
@@ -34,7 +34,7 @@ class MiniModel
34
34
  end
35
35
 
36
36
  def respond_to_missing?(symbol, include_private = false)
37
- @attributes.has_key?(symbol)
37
+ @attributes.key?(symbol)
38
38
  end
39
39
 
40
40
  class DuplicateKeyError < StandardError
@@ -59,6 +59,16 @@ class MiniModel
59
59
  @auto_increment = options[:auto_increment] ? 1 : nil
60
60
  end
61
61
 
62
+ def keys
63
+ all.map(&primary_key)
64
+ end
65
+
66
+ def options(text_attribute)
67
+ all.each_with_object({}) do |model, hash|
68
+ hash[model.read_attribute(text_attribute)] = model.read_attribute(primary_key)
69
+ end
70
+ end
71
+
62
72
  def insert(attributes)
63
73
  unless @auto_increment.nil?
64
74
  attributes[primary_key] = @auto_increment
@@ -70,15 +80,15 @@ class MiniModel
70
80
 
71
81
  pkey = object.send(primary_key)
72
82
 
73
- if index.has_key?(pkey)
83
+ if index.key?(pkey)
74
84
  raise DuplicateKeyError
75
85
  end
76
86
 
77
87
  index[pkey] = object
78
88
  end
79
89
 
80
- def find(key)
81
- index[key]
90
+ def find(primary_key, &block)
91
+ index.fetch(primary_key, &block)
82
92
  end
83
93
 
84
94
  def load_from(path)
@@ -1,14 +1,20 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'minimodel'
3
- s.version = '0.2.0'
3
+ s.version = '2.0.1'
4
+ s.license = 'LGPL-3.0'
4
5
  s.platform = Gem::Platform::RUBY
5
6
  s.authors = ['Tim Craft']
6
7
  s.email = ['mail@timcraft.com']
7
- s.homepage = 'http://github.com/timcraft/minimodel'
8
- s.description = 'A little library for defining little models'
8
+ s.homepage = 'https://github.com/timcraft/minimodel'
9
+ s.description = 'A little Ruby library for defining little models'
9
10
  s.summary = 'See description'
10
- s.files = Dir.glob('{lib,spec}/**/*') + %w(README.txt Rakefile minimodel.gemspec)
11
- s.add_development_dependency('activesupport', ['>= 3.0.3'])
12
- s.add_development_dependency('activerecord', ['>= 3.0.3'])
11
+ s.files = Dir.glob('lib/**/*.rb') + %w[CHANGES.md LICENSE.txt README.md minimodel.gemspec]
12
+ s.required_ruby_version = '>= 1.9.3'
13
13
  s.require_path = 'lib'
14
+ s.metadata = {
15
+ 'homepage' => 'https://github.com/timcraft/minimodel',
16
+ 'source_code_uri' => 'https://github.com/timcraft/minimodel',
17
+ 'bug_tracker_uri' => 'https://github.com/timcraft/minimodel/issues',
18
+ 'changelog_uri' => 'https://github.com/timcraft/minimodel/blob/main/CHANGES.md'
19
+ }
14
20
  end
metadata CHANGED
@@ -1,76 +1,53 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minimodel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 2.0.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Tim Craft
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2011-10-11 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: activesupport
16
- requirement: &9966180 !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: 3.0.3
22
- type: :development
23
- prerelease: false
24
- version_requirements: *9966180
25
- - !ruby/object:Gem::Dependency
26
- name: activerecord
27
- requirement: &9965800 !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: 3.0.3
33
- type: :development
34
- prerelease: false
35
- version_requirements: *9965800
36
- description: A little library for defining little models
11
+ date: 2020-11-03 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A little Ruby library for defining little models
37
14
  email:
38
15
  - mail@timcraft.com
39
16
  executables: []
40
17
  extensions: []
41
18
  extra_rdoc_files: []
42
19
  files:
43
- - lib/minimodel/associations.rb
20
+ - CHANGES.md
21
+ - LICENSE.txt
22
+ - README.md
44
23
  - lib/minimodel.rb
45
- - spec/colour_spec.rb
46
- - spec/currency_data.yml
47
- - spec/currency_spec.rb
48
- - spec/dutch_education_spec.rb
49
- - README.txt
50
- - Rakefile
24
+ - lib/minimodel/associations.rb
51
25
  - minimodel.gemspec
52
- homepage: http://github.com/timcraft/minimodel
53
- licenses: []
54
- post_install_message:
26
+ homepage: https://github.com/timcraft/minimodel
27
+ licenses:
28
+ - LGPL-3.0
29
+ metadata:
30
+ homepage: https://github.com/timcraft/minimodel
31
+ source_code_uri: https://github.com/timcraft/minimodel
32
+ bug_tracker_uri: https://github.com/timcraft/minimodel/issues
33
+ changelog_uri: https://github.com/timcraft/minimodel/blob/main/CHANGES.md
34
+ post_install_message:
55
35
  rdoc_options: []
56
36
  require_paths:
57
37
  - lib
58
38
  required_ruby_version: !ruby/object:Gem::Requirement
59
- none: false
60
39
  requirements:
61
- - - ! '>='
40
+ - - ">="
62
41
  - !ruby/object:Gem::Version
63
- version: '0'
42
+ version: 1.9.3
64
43
  required_rubygems_version: !ruby/object:Gem::Requirement
65
- none: false
66
44
  requirements:
67
- - - ! '>='
45
+ - - ">="
68
46
  - !ruby/object:Gem::Version
69
47
  version: '0'
70
48
  requirements: []
71
- rubyforge_project:
72
- rubygems_version: 1.8.10
73
- signing_key:
74
- specification_version: 3
49
+ rubygems_version: 3.1.4
50
+ signing_key:
51
+ specification_version: 4
75
52
  summary: See description
76
53
  test_files: []
data/README.txt DELETED
@@ -1,27 +0,0 @@
1
- A little library for defining little models.
2
-
3
- Many apps use small "read only" datasets that can easily be held in memory,
4
- for example: currency data, country data, colour data, advertising banners,
5
- options for select boxes, payment plans etc. Sometimes it's useful to model
6
- this data without using your database, and that's what minimodel is for.
7
-
8
- Quick example:
9
-
10
- require 'minimodel'
11
-
12
- class Currency < MiniModel
13
- indexed_by :code
14
-
15
- insert code: 'EUR', name: 'Euro'
16
- insert code: 'GBP', name: 'Pound sterling'
17
- insert code: 'USD', name: 'United States dollar'
18
- end
19
-
20
-
21
- The Currency class will respond to #count (returning the total number of
22
- currencies), #all (returning an array of currency objects), and #find
23
- (to lookup a specific currency by its code). Just like ActiveRecord.
24
-
25
- Take a look at spec/*_spec.rb for more examples.
26
-
27
- Have fun.
data/Rakefile DELETED
@@ -1,5 +0,0 @@
1
- require 'rake/testtask'
2
-
3
- Rake::TestTask.new do |t|
4
- t.test_files = FileList['spec/*_spec.rb']
5
- end
@@ -1,16 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minimodel'
3
-
4
- class Colour < MiniModel
5
- indexed_by :id, auto_increment: true
6
-
7
- insert name: 'Blue', hexdigits: '0000FF'
8
- insert name: 'Red', hexdigits: 'FF0000'
9
- insert name: 'Green', hexdigits: '00FF00'
10
- end
11
-
12
- describe Colour do
13
- it 'should assign auto incrementing id values' do
14
- Colour.all.map(&:id).must_equal [1, 2, 3]
15
- end
16
- end
@@ -1,8 +0,0 @@
1
- EUR:
2
- name: Euro
3
-
4
- GBP:
5
- name: Pound sterling
6
-
7
- USD:
8
- name: United States dollar
@@ -1,108 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minimodel'
3
- require 'json'
4
-
5
- class Currency < MiniModel
6
- indexed_by :code
7
-
8
- load_from 'spec/currency_data.yml'
9
-
10
- insert code: 'INR', name: 'Indian rupee'
11
- insert code: 'JPY', name: 'Japanese yen'
12
- end
13
-
14
- describe 'A currency object' do
15
- before do
16
- @euro = Currency.new(code: 'EUR', name: 'Euro')
17
- end
18
-
19
- it 'should respond_to?(:code) and respond_to?(:name)' do
20
- @euro.respond_to?(:code).must_equal true
21
- @euro.respond_to?(:name).must_equal true
22
- end
23
-
24
- it 'should have attribute reader methods' do
25
- @euro.code.must_equal 'EUR'
26
- @euro.name.must_equal 'Euro'
27
- end
28
-
29
- describe '#eql?' do
30
- describe 'when passed the same currency object' do
31
- it 'should return true' do
32
- @euro.eql?(@euro).must_equal true
33
- @euro.eql?(Currency.new(code: 'EUR', name: 'Euro')).must_equal true
34
- end
35
- end
36
-
37
- describe 'when passed a different currency object' do
38
- it 'should return false' do
39
- @euro.eql?(Currency.new(code: 'GBP', name: 'Pound sterling')).must_equal false
40
- end
41
- end
42
- end
43
-
44
- describe '#to_hash' do
45
- it 'should return a hash containing the object attributes' do
46
- @euro.to_hash.must_be_kind_of Hash
47
- @euro.to_hash.must_equal code: 'EUR', name: 'Euro'
48
- end
49
- end
50
-
51
- describe '#to_json' do
52
- it 'should return a string containing a JSON object' do
53
- @euro.to_json.must_equal '{"code":"EUR","name":"Euro"}'
54
- end
55
- end
56
-
57
- describe '#read_attribute' do
58
- it 'should return the value corresponding to the given attribute name' do
59
- @euro.read_attribute(:code).must_equal 'EUR'
60
- @euro.read_attribute(:name).must_equal 'Euro'
61
- end
62
- end
63
- end
64
-
65
- describe Currency do
66
- describe '#all' do
67
- it 'should return an array containing currency objects' do
68
- Currency.all.must_be_kind_of Array
69
- Currency.all.all? { |object| object.must_be_kind_of Currency }
70
- end
71
- end
72
-
73
- describe '#primary_key' do
74
- it 'should return the primary key specified using #indexed_by' do
75
- Currency.primary_key.must_equal :code
76
- end
77
- end
78
-
79
- describe '#count' do
80
- it 'should return the total number of currencies defined' do
81
- Currency.count.must_equal 5
82
- end
83
- end
84
-
85
- describe '#find' do
86
- describe 'when passed a valid currency code' do
87
- it 'should return the correct currency' do
88
- currency = Currency.find('EUR')
89
-
90
- currency.must_be_kind_of Currency
91
- currency.code.must_equal 'EUR'
92
- currency.name.must_equal 'Euro'
93
- end
94
- end
95
-
96
- describe 'when passed an invalid currency code' do
97
- it 'should return nil' do
98
- Currency.find('FOO').must_be_nil
99
- end
100
- end
101
- end
102
-
103
- describe '#insert' do
104
- it 'should raise an error when passed a key that already exists' do
105
- proc { Currency.insert(code: 'EUR', name: 'Euro') }.must_raise MiniModel::DuplicateKeyError
106
- end
107
- end
108
- end
@@ -1,137 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minimodel'
3
- require 'minimodel/associations'
4
- require 'active_record'
5
-
6
- ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
7
-
8
- ActiveRecord::Schema.define(:version => 1) do
9
- create_table :courses, :force => true do |t|
10
- t.string :name, :index => true
11
- t.string :level_name, :index => true
12
- end
13
- end
14
-
15
- class Level < MiniModel
16
- indexed_by :name
17
-
18
- has_many :courses
19
- has_many :profiles
20
-
21
- insert name: 'VMBO-T'
22
- insert name: 'HAVO'
23
- insert name: 'VWO'
24
- end
25
-
26
- class Profile < MiniModel
27
- indexed_by :id, auto_increment: true
28
-
29
- belongs_to :level
30
-
31
- insert level_name: 'VMBO-T', name: 'Techniek'
32
- insert level_name: 'VMBO-T', name: 'Zorg en Welzijn'
33
- insert level_name: 'VMBO-T', name: 'Economie'
34
- insert level_name: 'VMBO-T', name: 'Landbouw'
35
-
36
- insert level_name: 'HAVO', name: 'Economie en Maatschappij'
37
- insert level_name: 'HAVO', name: 'Cultuur en Maatschappij'
38
- insert level_name: 'HAVO', name: 'Natuur en Gezondheid'
39
- insert level_name: 'HAVO', name: 'Natuur en Techniek'
40
-
41
- insert level_name: 'VWO', name: 'Economie en Maatschappij'
42
- insert level_name: 'VWO', name: 'Cultuur en Maatschappij'
43
- insert level_name: 'VWO', name: 'Natuur en Gezondheid'
44
- insert level_name: 'VWO', name: 'Natuur en Techniek'
45
- end
46
-
47
- class Course < ActiveRecord::Base
48
- def level
49
- @level ||= Level.find(level_name)
50
- end
51
- end
52
-
53
- Level.all.each do |level|
54
- for course_name in %w( Nederlands Engels Duits )
55
- Course.create!(level_name: level.name, name: "#{level.name}/#{course_name}")
56
- end
57
- end
58
-
59
- describe 'A level object' do
60
- before do
61
- @level = Level.find('VMBO-T')
62
-
63
- @profile_names = ['Economie', 'Landbouw', 'Techniek', 'Zorg en Welzijn']
64
-
65
- @course_names = %w( VMBO-T/Duits VMBO-T/Engels VMBO-T/Nederlands )
66
- end
67
-
68
- describe '#profiles' do
69
- it 'should be enumerable' do
70
- @level.profiles.must_respond_to :each
71
- @level.profiles.class.ancestors.must_include Enumerable
72
- end
73
-
74
- describe '#size' do
75
- it 'should return the number of profiles linked to this level' do
76
- @level.profiles.size.must_equal 4
77
- end
78
- end
79
-
80
- describe '#to_a' do
81
- it 'should return an array containing the correct profile objects' do
82
- profiles = @level.profiles.to_a
83
-
84
- profiles.must_be_kind_of Array
85
- profiles.map(&:name).sort.must_equal @profile_names
86
- end
87
- end
88
- end
89
-
90
- describe '#courses' do
91
- it 'should be enumerable' do
92
- @level.courses.must_respond_to :each
93
- @level.courses.class.ancestors.must_include Enumerable
94
- end
95
-
96
- describe '#size' do
97
- it 'should return the number of courses linked to this level' do
98
- @level.courses.size.must_equal 3
99
- end
100
- end
101
-
102
- describe '#to_a' do
103
- it 'should return an array containing the correct course objects' do
104
- courses = @level.courses.to_a
105
-
106
- courses.must_be_kind_of Array
107
- courses.map(&:name).sort.must_equal @course_names
108
- end
109
- end
110
- end
111
- end
112
-
113
- describe 'A profile object' do
114
- before do
115
- @profile = Profile.find(8)
116
- end
117
-
118
- describe '#level' do
119
- it 'should return the correct level object' do
120
- @profile.level.must_be_kind_of Level
121
- @profile.level.name.must_equal 'HAVO'
122
- end
123
- end
124
- end
125
-
126
- describe 'A course object' do
127
- before do
128
- @course = Course.find_by_name('VWO/Engels')
129
- end
130
-
131
- describe '#level' do
132
- it 'should return the correct level object' do
133
- @course.level.must_be_kind_of Level
134
- @course.level.name.must_equal 'VWO'
135
- end
136
- end
137
- end