datamappify 0.52.0 → 0.53.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd079889034877268b854c9c1402e747eb84348a
4
- data.tar.gz: ea1988a5cea43748d9d55658e999b9c1a95a9de6
3
+ metadata.gz: bad8103a3c5c165af76967bc3b93b2c1a79c303d
4
+ data.tar.gz: a84ea4a4f05701f9bdbbb4ef68baba89f2887dc9
5
5
  SHA512:
6
- metadata.gz: 18fde8f5ddccee08904440fdd706f0563130a78566a8860bc3a67017b35320444655db5226e6019d73e29e069750a80ddc267dd7e0bcc63d64a84daf05d263c8
7
- data.tar.gz: 91fa0a11fd1af61e398b0b22e6dcad429c4123653dafabcb9c70bc39681ce0a8a9b1e61944996f688eac8221b771344a02679f9b137d3cc278a57a4b6b9114f6
6
+ metadata.gz: 49c79d48411f0e71f550aeba3d0022cae4e8bf1a61aae621493164da4f64942034f348e34a0a1fe4a66221bc86cf6a744c22cf232c8722ca2580336f758b4463
7
+ data.tar.gz: e6e75cdce7912e86ce5e023f3e44fee19e6c890b23c77159b883db53a53ee92b295e456aca40fef871ca997252c49139dfde9ac6190abf317707e55e501ddccc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## master
2
2
 
3
+ ## 0.53.0 [2013-06-27]
4
+
5
+ - Added support for mapping to namespaced data models.
6
+
3
7
  ## 0.52.0 [2013-06-26]
4
8
 
5
9
  - Added support for reverse mapping attributes.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Datamappify [![Gem Version](https://badge.fury.io/rb/datamappify.png)](http://badge.fury.io/rb/datamappify) [![Build Status](https://api.travis-ci.org/fredwu/datamappify.png?branch=master)](http://travis-ci.org/fredwu/datamappify) [![Coverage Status](https://coveralls.io/repos/fredwu/datamappify/badge.png)](https://coveralls.io/r/fredwu/datamappify) [![Code Climate](https://codeclimate.com/github/fredwu/datamappify.png)](https://codeclimate.com/github/fredwu/datamappify)
2
2
 
3
- #### Compose, decouple and manage domain logic and data persistence separately. Works great with forms!
3
+ #### Compose, decouple and manage domain logic and data persistence separately. Works particularly great for composing form objects!
4
4
 
5
5
  ## Overview
6
6
 
@@ -27,7 +27,7 @@ Datamappify consists of three components:
27
27
 
28
28
  Below is a high level and somewhat simplified overview of Datamappify's architecture.
29
29
 
30
- ![](http://i.imgur.com/byt6P3f.png)
30
+ ![](http://i.imgur.com/I9GpLds.png)
31
31
 
32
32
  Note: Datamappify is NOT affiliated with the [Datamapper](https://github.com/datamapper/) project.
33
33
 
data/datamappify.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Datamappify::VERSION
9
9
  spec.authors = ["Fred Wu"]
10
10
  spec.email = ["ifredwu@gmail.com"]
11
- spec.description = %q{Compose, decouple and manage domain logic and data persistence separately. Works great with forms!}
11
+ spec.description = %q{Compose, decouple and manage domain logic and data persistence separately. Works particularly great for composing form objects!}
12
12
  spec.summary = spec.description
13
13
  spec.homepage = "https://github.com/fredwu/datamappify"
14
14
  spec.license = "MIT"
@@ -56,7 +56,7 @@ module Datamappify
56
56
 
57
57
  # @example
58
58
  #
59
- # UserComment
59
+ # Namespaced::UserComment
60
60
  #
61
61
  # @return [Class]
62
62
  def source_class
@@ -69,7 +69,7 @@ module Datamappify
69
69
  #
70
70
  # @return [String]
71
71
  def source_name
72
- @source_name ||= source_class_name.underscore
72
+ @source_name ||= source_class_name.demodulize.underscore
73
73
  end
74
74
 
75
75
  # @example
@@ -141,8 +141,9 @@ module Datamappify
141
141
  provider_name != primary_provider_name
142
142
  end
143
143
 
144
+ # @return [Boolean]
144
145
  def reverse_mapped?
145
- @options[:via]
146
+ !!@options[:via]
146
147
  end
147
148
 
148
149
  private
@@ -150,7 +151,7 @@ module Datamappify
150
151
  # @return [Array<String>]
151
152
  # an array with provider name, source class name and source attribute name
152
153
  def parse_source(source)
153
- provider_name, source_class_and_attribute = source.split('::')
154
+ provider_name, source_class_and_attribute = source.split('::', 2)
154
155
 
155
156
  [provider_name, *source_class_and_attribute.split('#')]
156
157
  end
@@ -9,9 +9,15 @@ module Datamappify
9
9
  #
10
10
  # @return [ActiveRecord::Base]
11
11
  def build_record_class(source_class_name)
12
- Datamappify::Data::Record::ActiveRecord.const_set(
13
- source_class_name, Class.new(::ActiveRecord::Base)
14
- )
12
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
13
+ module Datamappify::Data::Record::ActiveRecord
14
+ class #{source_class_name} < ::ActiveRecord::Base
15
+ self.table_name = '#{source_class_name.pluralize.gsub('::', '_').underscore}'
16
+ end
17
+ end
18
+ CODE
19
+
20
+ Datamappify::Data::Record::ActiveRecord.const_get(source_class_name)
15
21
  end
16
22
 
17
23
  # @return [void]
@@ -35,8 +35,18 @@ module Datamappify
35
35
  # @return [Class]
36
36
  # the data record class
37
37
  def find_or_build_record_class(source_class_name)
38
- if records_namespace.const_defined?(source_class_name, false)
39
- records_namespace.const_get(source_class_name)
38
+ namespace = build_or_return_namespace(source_class_name)
39
+ record_class = source_class_name.safe_constantize
40
+
41
+ # check for existing record class
42
+ if record_class && !entity_class?(source_class_name)
43
+ record_class
44
+
45
+ # check for existing record class in the Datamappify::Data::Record::Provider namespace
46
+ elsif namespace.const_defined?(source_class_name.demodulize, false)
47
+ namespace.const_get(source_class_name.demodulize)
48
+
49
+ # no existing record class is found, let's build it
40
50
  else
41
51
  build_record_class(source_class_name)
42
52
  end
@@ -44,6 +54,26 @@ module Datamappify
44
54
 
45
55
  private
46
56
 
57
+ # @return [Boolean]
58
+ def entity_class?(source_class_name)
59
+ source_class_name.constantize.ancestors.include?(Datamappify::Entity)
60
+ end
61
+
62
+ # Builds or returns the namespace for the source class
63
+ #
64
+ # @param source_class_name [String]
65
+ #
66
+ # @return [Module]
67
+ def build_or_return_namespace(source_class_name)
68
+ source_class_name.deconstantize.split('::').inject(records_namespace) do |namespaces, namespace|
69
+ if namespaces.const_defined?(namespace, false)
70
+ namespaces.const_get(namespace)
71
+ else
72
+ namespaces.const_set(namespace, Module.new)
73
+ end
74
+ end
75
+ end
76
+
47
77
  # The namespace for the data records, e.g. +Datamappify::Data::Record::ActiveRecord+
48
78
  #
49
79
  # @return [Module]
@@ -9,11 +9,15 @@ module Datamappify
9
9
  #
10
10
  # @return [Sequel::Model]
11
11
  def build_record_class(source_class_name)
12
- Record::Sequel.const_set(
13
- source_class_name, Class.new(::Sequel::Model(source_class_name.pluralize.underscore.to_sym))
14
- ).tap do |klass|
15
- klass.raise_on_save_failure = true
16
- end
12
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
13
+ module Datamappify::Data::Record::Sequel
14
+ class #{source_class_name} < ::Sequel::Model(:#{source_class_name.pluralize.gsub('::', '_').underscore})
15
+ raise_on_save_failure = true
16
+ end
17
+ end
18
+ CODE
19
+
20
+ Datamappify::Data::Record::Sequel.const_get(source_class_name)
17
21
  end
18
22
 
19
23
  # @param attribute (see Record#build_association)
@@ -1,3 +1,3 @@
1
1
  module Datamappify
2
- VERSION = '0.52.0'
2
+ VERSION = '0.53.0'
3
3
  end
@@ -9,34 +9,22 @@ describe Datamappify::Entity do
9
9
  :gfx => 'Voodoo',
10
10
  :vendor => 'Compaq',
11
11
  :software_os => 'OS X',
12
- :software_osx_id => 1,
13
- :software_windows_id => 2,
14
- :software_linux_id => 3,
15
- :software_vendor => 'Lotus',
16
- :game_os => 'OS X',
17
- :game_osx_id => 1,
18
- :game_windows_id => 2,
19
- :game_linux_id => 3,
20
- :game_vendor => 'Lotus'
12
+ :software_vendor => 'Apple',
13
+ :game_os => 'Orbit OS',
14
+ :game_vendor => 'SONY'
21
15
  })
22
16
  end
23
17
 
24
- its(:brand) { should == 'Fruit' }
25
- its(:cpu) { should == '286' }
26
- its(:ram) { should == 4242 }
27
- its(:hdd) { should == 65536 }
28
- its(:gfx) { should == 'Voodoo' }
29
- its(:vendor) { should == 'Compaq' }
30
- its(:software_os) { should == 'OS X' }
31
- its(:software_osx_id) { should == 1 }
32
- its(:software_windows_id) { should == 2 }
33
- its(:software_linux_id) { should == 3 }
34
- its(:software_vendor) { should == 'Lotus' }
35
- its(:game_os) { should == 'OS X' }
36
- its(:game_osx_id) { should == 1 }
37
- its(:game_windows_id) { should == 2 }
38
- its(:game_linux_id) { should == 3 }
39
- its(:game_vendor) { should == 'Lotus' }
18
+ its(:brand) { should == 'Fruit' }
19
+ its(:cpu) { should == '286' }
20
+ its(:ram) { should == 4242 }
21
+ its(:hdd) { should == 65536 }
22
+ its(:gfx) { should == 'Voodoo' }
23
+ its(:vendor) { should == 'Compaq' }
24
+ its(:software_os) { should == 'OS X' }
25
+ its(:software_vendor) { should == 'Apple' }
26
+ its(:game_os) { should == 'Orbit OS' }
27
+ its(:game_vendor) { should == 'SONY' }
40
28
 
41
29
  describe "validation" do
42
30
  context "valid" do
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "namespaced mapping" do |data_provider|
4
+ let!(:computer_repository) { "ComputerRepository#{data_provider}".constantize }
5
+ let(:new_computer) {
6
+ Computer.new({
7
+ :brand => 'Fruit',
8
+ :cpu => '286',
9
+ :ram => 4242,
10
+ :gfx => 'Voodoo',
11
+ :vendor => 'Compaq',
12
+ :software_os => 'OS X',
13
+ :software_vendor => 'Apple',
14
+ :game_os => 'Orbit OS',
15
+ :game_vendor => 'SONY'
16
+ })
17
+ }
18
+
19
+ context "#{data_provider}" do
20
+ describe "entity" do
21
+ let!(:computer) { computer_repository.save!(new_computer) }
22
+
23
+ subject { computer_repository.find(computer.id) }
24
+
25
+ its(:brand) { should == 'Fruit' }
26
+ its(:cpu) { should == '286' }
27
+ its(:ram) { should == 4242 }
28
+ its(:hdd) { should == 65536 }
29
+ its(:gfx) { should == 'Voodoo' }
30
+ its(:vendor) { should == 'Compaq' }
31
+ its(:software_os) { should == 'OS X' }
32
+ its(:software_vendor) { should == 'Apple' }
33
+ its(:game_os) { should == 'Orbit OS' }
34
+ its(:game_vendor) { should == 'SONY' }
35
+ end
36
+ end
37
+ end
38
+
39
+ describe Datamappify::Repository do
40
+ DATA_PROVIDERS.each do |data_provider|
41
+ it_behaves_like "namespaced mapping", data_provider
42
+ end
43
+ end
@@ -1,14 +1,14 @@
1
- require_relative 'computer_hardware'
2
- require_relative 'computer_software'
1
+ require_relative 'computer_component/hardware'
2
+ require_relative 'computer_component/software'
3
3
 
4
4
  class Computer
5
5
  include Datamappify::Entity
6
6
 
7
7
  attribute :brand, String
8
8
 
9
- attributes_from ComputerHardware
10
- attributes_from ComputerSoftware, :prefix_with => :software
11
- attributes_from ComputerSoftware, :prefix_with => :game
9
+ attributes_from ComputerComponent::Hardware
10
+ attributes_from ComputerComponent::Software, :prefix_with => :software
11
+ attributes_from ComputerComponent::Software, :prefix_with => :game
12
12
 
13
13
  validates :brand, :presence => true
14
14
  end
@@ -0,0 +1,14 @@
1
+ module ComputerComponent
2
+ class Hardware
3
+ include Datamappify::Entity
4
+
5
+ attribute :cpu, String
6
+ attribute :ram, Integer, :default => 8192
7
+ attribute :hdd, Integer, :default => 65536
8
+ attribute :gfx, String
9
+ attribute :vendor, String
10
+
11
+ validates :ram, :hdd, :numericality => { :greater_than_or_equal_to => 4096 }
12
+ validates :hdd, :numericality => { :less_than_or_equal_to => 65536 }
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ module ComputerComponent
2
+ class Software
3
+ include Datamappify::Entity
4
+
5
+ attribute :os, String
6
+ attribute :vendor, String
7
+
8
+ validates_presence_of :os
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ class ComputerSoftware < ActiveRecord::Base
2
+ self.table_name = 'computer_component_softwares'
3
+ end
4
+
5
+ class ComputerRepositoryActiveRecord
6
+ include Datamappify::Repository
7
+
8
+ for_entity Computer
9
+ default_provider :ActiveRecord
10
+
11
+ map_attribute :cpu, 'ActiveRecord::ComputerComponent::Hardware#cpu'
12
+ map_attribute :ram, 'ActiveRecord::ComputerComponent::Hardware#ram'
13
+ map_attribute :hdd, 'ActiveRecord::ComputerComponent::Hardware#hdd'
14
+ map_attribute :gfx, 'ActiveRecord::ComputerComponent::Hardware#gfx'
15
+ map_attribute :vendor, 'ActiveRecord::ComputerComponent::Hardware#vendor'
16
+ map_attribute :software_os, 'ActiveRecord::ComputerSoftware#os'
17
+ map_attribute :software_vendor, 'ActiveRecord::ComputerSoftware#vendor'
18
+ map_attribute :game_os, 'ActiveRecord::ComputerSoftware#os', :via => :game_id
19
+ map_attribute :game_vendor, 'ActiveRecord::ComputerSoftware#vendor', :via => :game_id
20
+ end
@@ -0,0 +1,16 @@
1
+ class ComputerRepositorySequel
2
+ include Datamappify::Repository
3
+
4
+ for_entity Computer
5
+ default_provider :Sequel
6
+
7
+ map_attribute :cpu, 'Sequel::ComputerComponent::Hardware#cpu'
8
+ map_attribute :ram, 'Sequel::ComputerComponent::Hardware#ram'
9
+ map_attribute :hdd, 'Sequel::ComputerComponent::Hardware#hdd'
10
+ map_attribute :gfx, 'Sequel::ComputerComponent::Hardware#gfx'
11
+ map_attribute :vendor, 'Sequel::ComputerComponent::Hardware#vendor'
12
+ map_attribute :software_os, 'Sequel::ComputerComponent::Software#os'
13
+ map_attribute :software_vendor, 'Sequel::ComputerComponent::Software#vendor'
14
+ map_attribute :game_os, 'Sequel::ComputerComponent::Software#os', :via => :game_id
15
+ map_attribute :game_vendor, 'Sequel::ComputerComponent::Software#vendor', :via => :game_id
16
+ end
@@ -76,5 +76,32 @@ ActiveRecord::Migration.suppress_messages do
76
76
  t.references :post
77
77
  t.timestamps
78
78
  end
79
+
80
+ create_table :computers do |t|
81
+ t.string :brand
82
+ t.references :game
83
+ t.timestamps
84
+ end
85
+
86
+ create_table :computer_component_hardwares do |t|
87
+ t.string :brand
88
+ t.string :cpu
89
+ t.integer :ram
90
+ t.integer :hdd
91
+ t.string :gfx
92
+ t.string :vendor
93
+ t.references :computer
94
+ t.timestamps
95
+ end
96
+
97
+ create_table :computer_component_softwares do |t|
98
+ t.string :os
99
+ t.string :vendor
100
+ t.references :osx
101
+ t.references :windows
102
+ t.references :linux
103
+ t.references :computer
104
+ t.timestamps
105
+ end
79
106
  end
80
107
  end
@@ -89,7 +89,40 @@ DB.create_table :authors do |t|
89
89
  primary_key :id
90
90
  String :name
91
91
  String :bio
92
- String :post_id
92
+ foreign_key :post_id
93
+ DateTime :created_at
94
+ DateTime :updated_at
95
+ end
96
+
97
+ DB.create_table :computers do |t|
98
+ primary_key :id
99
+ String :brand
100
+ foreign_key :game_id
101
+ DateTime :created_at
102
+ DateTime :updated_at
103
+ end
104
+
105
+ DB.create_table :computer_component_hardwares do |t|
106
+ primary_key :id
107
+ String :brand
108
+ String :cpu
109
+ Integer :ram
110
+ Integer :hdd
111
+ String :gfx
112
+ String :vendor
113
+ foreign_key :computer_id
114
+ DateTime :created_at
115
+ DateTime :updated_at
116
+ end
117
+
118
+ DB.create_table :computer_component_softwares do |t|
119
+ primary_key :id
120
+ String :os
121
+ String :vendor
122
+ foreign_key :computer_id
123
+ foreign_key :osx_id
124
+ foreign_key :windows_id
125
+ foreign_key :linux_id
93
126
  DateTime :created_at
94
127
  DateTime :updated_at
95
128
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datamappify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.52.0
4
+ version: 0.53.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Wu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-26 00:00:00.000000000 Z
11
+ date: 2013-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: virtus
@@ -253,7 +253,7 @@ dependencies:
253
253
  - !ruby/object:Gem::Version
254
254
  version: 1.0.1
255
255
  description: Compose, decouple and manage domain logic and data persistence separately.
256
- Works great with forms!
256
+ Works particularly great for composing form objects!
257
257
  email:
258
258
  - ifredwu@gmail.com
259
259
  executables: []
@@ -349,6 +349,7 @@ files:
349
349
  - spec/repository/dirty_persistence_spec.rb
350
350
  - spec/repository/dirty_tracking_spec.rb
351
351
  - spec/repository/finders_spec.rb
352
+ - spec/repository/namespaced_mapping_spec.rb
352
353
  - spec/repository/persistence_spec.rb
353
354
  - spec/repository/reverse_mapped_spec.rb
354
355
  - spec/repository/transactions_spec.rb
@@ -359,8 +360,8 @@ files:
359
360
  - spec/support/entities/author.rb
360
361
  - spec/support/entities/comment.rb
361
362
  - spec/support/entities/computer.rb
362
- - spec/support/entities/computer_hardware.rb
363
- - spec/support/entities/computer_software.rb
363
+ - spec/support/entities/computer_component/hardware.rb
364
+ - spec/support/entities/computer_component/software.rb
364
365
  - spec/support/entities/group.rb
365
366
  - spec/support/entities/hero_user.rb
366
367
  - spec/support/entities/post.rb
@@ -370,6 +371,7 @@ files:
370
371
  - spec/support/repositories/active_record/admin_user_repository.rb
371
372
  - spec/support/repositories/active_record/author_repository.rb
372
373
  - spec/support/repositories/active_record/comment_repository.rb
374
+ - spec/support/repositories/active_record/computer_repository.rb
373
375
  - spec/support/repositories/active_record/group_repository.rb
374
376
  - spec/support/repositories/active_record/post_repository.rb
375
377
  - spec/support/repositories/active_record/role_repository.rb
@@ -379,6 +381,7 @@ files:
379
381
  - spec/support/repositories/sequel/admin_user_repository.rb
380
382
  - spec/support/repositories/sequel/author_repository.rb
381
383
  - spec/support/repositories/sequel/comment_repository.rb
384
+ - spec/support/repositories/sequel/computer_repository.rb
382
385
  - spec/support/repositories/sequel/group_repository.rb
383
386
  - spec/support/repositories/sequel/post_repository.rb
384
387
  - spec/support/repositories/sequel/role_repository.rb
@@ -413,7 +416,7 @@ rubygems_version: 2.0.3
413
416
  signing_key:
414
417
  specification_version: 4
415
418
  summary: Compose, decouple and manage domain logic and data persistence separately.
416
- Works great with forms!
419
+ Works particularly great for composing form objects!
417
420
  test_files:
418
421
  - spec/entity/composable_spec.rb
419
422
  - spec/entity/inheritance_spec.rb
@@ -424,6 +427,7 @@ test_files:
424
427
  - spec/repository/dirty_persistence_spec.rb
425
428
  - spec/repository/dirty_tracking_spec.rb
426
429
  - spec/repository/finders_spec.rb
430
+ - spec/repository/namespaced_mapping_spec.rb
427
431
  - spec/repository/persistence_spec.rb
428
432
  - spec/repository/reverse_mapped_spec.rb
429
433
  - spec/repository/transactions_spec.rb
@@ -434,8 +438,8 @@ test_files:
434
438
  - spec/support/entities/author.rb
435
439
  - spec/support/entities/comment.rb
436
440
  - spec/support/entities/computer.rb
437
- - spec/support/entities/computer_hardware.rb
438
- - spec/support/entities/computer_software.rb
441
+ - spec/support/entities/computer_component/hardware.rb
442
+ - spec/support/entities/computer_component/software.rb
439
443
  - spec/support/entities/group.rb
440
444
  - spec/support/entities/hero_user.rb
441
445
  - spec/support/entities/post.rb
@@ -445,6 +449,7 @@ test_files:
445
449
  - spec/support/repositories/active_record/admin_user_repository.rb
446
450
  - spec/support/repositories/active_record/author_repository.rb
447
451
  - spec/support/repositories/active_record/comment_repository.rb
452
+ - spec/support/repositories/active_record/computer_repository.rb
448
453
  - spec/support/repositories/active_record/group_repository.rb
449
454
  - spec/support/repositories/active_record/post_repository.rb
450
455
  - spec/support/repositories/active_record/role_repository.rb
@@ -454,6 +459,7 @@ test_files:
454
459
  - spec/support/repositories/sequel/admin_user_repository.rb
455
460
  - spec/support/repositories/sequel/author_repository.rb
456
461
  - spec/support/repositories/sequel/comment_repository.rb
462
+ - spec/support/repositories/sequel/computer_repository.rb
457
463
  - spec/support/repositories/sequel/group_repository.rb
458
464
  - spec/support/repositories/sequel/post_repository.rb
459
465
  - spec/support/repositories/sequel/role_repository.rb
@@ -1,12 +0,0 @@
1
- class ComputerHardware
2
- include Datamappify::Entity
3
-
4
- attribute :cpu, String
5
- attribute :ram, Integer, :default => 8192
6
- attribute :hdd, Integer, :default => 65536
7
- attribute :gfx, String
8
- attribute :vendor, String
9
-
10
- validates :ram, :hdd, :numericality => { :greater_than_or_equal_to => 4096 }
11
- validates :hdd, :numericality => { :less_than_or_equal_to => 65536 }
12
- end
@@ -1,12 +0,0 @@
1
- class ComputerSoftware
2
- include Datamappify::Entity
3
-
4
- attribute :os, String
5
- attribute :vendor, String
6
-
7
- references :osx
8
- references :windows
9
- references :linux
10
-
11
- validates_presence_of :os
12
- end