minimodel 0.2.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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