toy-model 0.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.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/Rakefile +3 -0
- data/lib/toy-model.rb +9 -0
- data/lib/toy-model/attribute_observer.rb +44 -0
- data/lib/toy-model/attribute_wrapper.rb +45 -0
- data/lib/toy-model/attributes.rb +24 -0
- data/lib/toy-model/attributes_collection.rb +17 -0
- data/lib/toy-model/railtie.rb +17 -0
- data/lib/toy-model/version.rb +3 -0
- data/spec/lib/attribute_observer_spec.rb +15 -0
- data/spec/lib/attributes_spec.rb +32 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/models/warrior.rb +4 -0
- data/spec/support/models/weapon.rb +4 -0
- data/spec/support/seeds.rb +4 -0
- data/toy-model.gemspec +27 -0
- metadata +106 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/lib/toy-model.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module ToyModel
|
2
|
+
class AttributeObserver
|
3
|
+
|
4
|
+
attr_accessor :attribute
|
5
|
+
|
6
|
+
def initialize model
|
7
|
+
return unless model.respond_to?(:use_toy_model?) && model.use_toy_model?
|
8
|
+
@model = model
|
9
|
+
unless ActiveRecord::Base.connection.table_exists? @model.table_name
|
10
|
+
Class.new(ActiveRecord::Migration).create_table(@model.table_name.to_sym) do |t|
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
@model.attributes.each do |attribute|
|
15
|
+
set_attribute(attribute)
|
16
|
+
@model.attr_accessible attribute.column
|
17
|
+
@model.attr_accessible :"#{attribute.column}_id" if attribute._as == :belongs_to
|
18
|
+
end
|
19
|
+
@model.reset_column_information
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_attribute attribute
|
23
|
+
return if attribute.skip_table_column?
|
24
|
+
add_attribute attribute
|
25
|
+
update_attribute attribute
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_attribute attribute
|
29
|
+
unless @model.column_names.include? attribute.to_table_column.to_s
|
30
|
+
Class.new(ActiveRecord::Migration).add_column @model.table_name.to_sym, attribute.to_table_column, attribute.to_table_type
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def update_attribute attribute
|
35
|
+
column = @model.columns.select{|c| c.name == attribute.to_table_column.to_s}.first
|
36
|
+
if column && column.type != attribute.to_table_type
|
37
|
+
Class.new(ActiveRecord::Migration).change_column @model.table_name, attribute.to_table_column, attribute.to_table_type
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ToyModel
|
2
|
+
class AttributeWrapper
|
3
|
+
|
4
|
+
attr_accessor :column, :parent, :_as, :_helper, :_options
|
5
|
+
|
6
|
+
def initialize column, parent
|
7
|
+
@column = column
|
8
|
+
@parent = parent
|
9
|
+
@_as = :string
|
10
|
+
end
|
11
|
+
|
12
|
+
def as value
|
13
|
+
@_as = value
|
14
|
+
enforce_relations
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def enforce_relations
|
19
|
+
@parent.send @_as, @column if [:has_many, :has_and_belongs_to_many, :has_one, :belongs_to].include? @_as
|
20
|
+
if [:has_many, :has_one].include? @_as
|
21
|
+
related = @column.to_s.singularize.classify.constantize
|
22
|
+
related.attribute(@parent.to_s.underscore.gsub(' ', '_').to_sym).as(:belongs_to)
|
23
|
+
ToyModel::AttributeObserver.new related
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_table_column
|
28
|
+
return nil if skip_table_column?
|
29
|
+
return :"#{@column}_id" if @_as == :belongs_to
|
30
|
+
@column
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_table_type
|
34
|
+
return nil if skip_table_column?
|
35
|
+
return :integer if @_as == :belongs_to
|
36
|
+
@_as
|
37
|
+
end
|
38
|
+
|
39
|
+
def skip_table_column?
|
40
|
+
[:has_many, :has_and_belongs_to_many, :has_one].include? @_as
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ToyModel::Attributes
|
2
|
+
|
3
|
+
mattr_accessor :toy_attributes
|
4
|
+
self.toy_attributes = []
|
5
|
+
|
6
|
+
def attribute value
|
7
|
+
wrapper = ToyModel::AttributeWrapper.new value, self
|
8
|
+
self.toy_attributes << wrapper
|
9
|
+
wrapper
|
10
|
+
end
|
11
|
+
|
12
|
+
def attrs *args
|
13
|
+
ToyModel::AttributesCollection.new self, *args
|
14
|
+
end
|
15
|
+
|
16
|
+
def attributes
|
17
|
+
toy_attributes.select{|a| a.parent == self}
|
18
|
+
end
|
19
|
+
|
20
|
+
def use_toy_model?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ToyModel
|
2
|
+
class AttributesCollection
|
3
|
+
|
4
|
+
attr_accessor :attributes
|
5
|
+
|
6
|
+
def initialize klass, *args
|
7
|
+
@attributes = []
|
8
|
+
args.each { |attr| @attributes << klass.attribute(attr) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(m, *args, &block)
|
12
|
+
@attributes.each { |attr| attr.send m, *args }
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ToyModel
|
2
|
+
|
3
|
+
def self.load! dir_path
|
4
|
+
ActiveRecord::Base.extend ToyModel::Attributes
|
5
|
+
Dir[dir_path].each do |file|
|
6
|
+
require file
|
7
|
+
ToyModel::AttributeObserver.new file.split('/').last.split('.').first.classify.constantize
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Engine < Rails::Engine
|
12
|
+
initializer 'toy_model.initialize', :after => :disable_dependency_loading do |app|
|
13
|
+
ToyModel.load! "#{Rails.root}/app/models/*.rb"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ToyModel::AttributeObserver do
|
4
|
+
|
5
|
+
it "creates table for new models" do
|
6
|
+
Warrior.table_exists?.should == true
|
7
|
+
end
|
8
|
+
|
9
|
+
it "changes the column type" do
|
10
|
+
Warrior.attributes.last.as(:text)
|
11
|
+
ToyModel::AttributeObserver.new Warrior
|
12
|
+
Warrior.columns_hash['story'].type.should == :text
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ToyModel::Attributes do
|
4
|
+
|
5
|
+
describe Warrior do
|
6
|
+
|
7
|
+
subject{ Warrior.first }
|
8
|
+
|
9
|
+
it{should respond_to(:name)}
|
10
|
+
its(:name){should == 'Mortaro'}
|
11
|
+
its(:name){should be_a(String)}
|
12
|
+
it{should respond_to(:weapons)}
|
13
|
+
|
14
|
+
it "automatically creates a has_many relation" do
|
15
|
+
subject.weapons.first.should == Weapon.first
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Weapon do
|
21
|
+
|
22
|
+
subject{ Weapon.first }
|
23
|
+
|
24
|
+
it{should respond_to(:warrior_id)}
|
25
|
+
it{should respond_to(:min_damage)}
|
26
|
+
it{should respond_to(:max_damage)}
|
27
|
+
its(:min_damage){should be_a(Fixnum)}
|
28
|
+
its(:warrior){should == Warrior.first}
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rails/all'
|
2
|
+
require 'toy-model'
|
3
|
+
require 'rspec-rails'
|
4
|
+
|
5
|
+
autoload :Warrior, "#{File.dirname(__FILE__)}/support/models/warrior.rb"
|
6
|
+
autoload :Weapon, "#{File.dirname(__FILE__)}/support/models/weapon.rb"
|
7
|
+
|
8
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: './toy_model.sqlite3')
|
9
|
+
ToyModel.load! "#{File.dirname(__FILE__)}/support/models/*.rb"
|
10
|
+
load "#{File.dirname(__FILE__)}/support/seeds.rb"
|
data/toy-model.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "toy-model/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
|
7
|
+
s.name = "toy-model"
|
8
|
+
s.version = ToyModel::VERSION
|
9
|
+
s.authors = ["Christian Mortaro"]
|
10
|
+
s.email = ["christian.mortaro@gmail.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Handles the models for the Toy Locomotive}
|
13
|
+
s.description = %q{Another layer above ActiveRecord}
|
14
|
+
|
15
|
+
s.rubyforge_project = "toy-model"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency "rails"
|
23
|
+
s.add_development_dependency "rspec-rails"
|
24
|
+
s.add_development_dependency "sqlite3"
|
25
|
+
s.add_development_dependency "shoulda"
|
26
|
+
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: toy-model
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Christian Mortaro
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: &3102792 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *3102792
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec-rails
|
27
|
+
requirement: &3101652 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *3101652
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: sqlite3
|
38
|
+
requirement: &3100428 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *3100428
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: shoulda
|
49
|
+
requirement: &3099576 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *3099576
|
58
|
+
description: Another layer above ActiveRecord
|
59
|
+
email:
|
60
|
+
- christian.mortaro@gmail.com
|
61
|
+
executables: []
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- .gitignore
|
66
|
+
- Gemfile
|
67
|
+
- Rakefile
|
68
|
+
- lib/toy-model.rb
|
69
|
+
- lib/toy-model/attribute_observer.rb
|
70
|
+
- lib/toy-model/attribute_wrapper.rb
|
71
|
+
- lib/toy-model/attributes.rb
|
72
|
+
- lib/toy-model/attributes_collection.rb
|
73
|
+
- lib/toy-model/railtie.rb
|
74
|
+
- lib/toy-model/version.rb
|
75
|
+
- spec/lib/attribute_observer_spec.rb
|
76
|
+
- spec/lib/attributes_spec.rb
|
77
|
+
- spec/spec_helper.rb
|
78
|
+
- spec/support/models/warrior.rb
|
79
|
+
- spec/support/models/weapon.rb
|
80
|
+
- spec/support/seeds.rb
|
81
|
+
- toy-model.gemspec
|
82
|
+
homepage: ''
|
83
|
+
licenses: []
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project: toy-model
|
102
|
+
rubygems_version: 1.8.16
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Handles the models for the Toy Locomotive
|
106
|
+
test_files: []
|