has_inherited 1.0.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.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +87 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/has_inherited.gemspec +54 -0
- data/lib/has_inherited.rb +177 -0
- data/spec/has_inherited_spec.rb +203 -0
- data/spec/spec_helper.rb +10 -0
- metadata +91 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Mark Turner
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
= has_inherited
|
2
|
+
|
3
|
+
Easily share variables between Rails models with inheritance.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
➜ ~ gem install has_inherited
|
8
|
+
|
9
|
+
== Using has_inheritable
|
10
|
+
|
11
|
+
The intention of this library is to make it easy to inherit particular variables between models in rails apps. We start with a parent model that will function as a pseudo-polymorphic association for children objects.
|
12
|
+
|
13
|
+
=== 1. Define a parent object
|
14
|
+
|
15
|
+
class Seo < ActiveRecord::Base
|
16
|
+
is_inheritable
|
17
|
+
end
|
18
|
+
|
19
|
+
Use the following as a migration guideline. *Note:* The table structure is important.
|
20
|
+
|
21
|
+
create_table :seos do |t|
|
22
|
+
t.integer :inheritable_id
|
23
|
+
t.string :inheritable_type
|
24
|
+
t.string :name, :limit => 50, :null => false
|
25
|
+
t.string :value
|
26
|
+
t.string :value_type
|
27
|
+
end
|
28
|
+
|
29
|
+
=== 2. Define child objects.
|
30
|
+
|
31
|
+
class Industry < ActiveRecord::Base
|
32
|
+
has_inherited :seo, :from => Seo
|
33
|
+
has_many :clients
|
34
|
+
end
|
35
|
+
|
36
|
+
This gives industry instances access to the seo namespace from the Seo object. In this case it will end up being `industry.seo.X`
|
37
|
+
|
38
|
+
class Client < ActiveRecord::Base
|
39
|
+
belongs_to :industry
|
40
|
+
has_many :stores
|
41
|
+
has_inherited :seo, :from => [:industry, :seo], :inherit_class => 'Seo'
|
42
|
+
end
|
43
|
+
|
44
|
+
This gives client instances access to the seo namespace from its associated industry. You also have to specify the `:inherit_class` so we know what table to look up.
|
45
|
+
|
46
|
+
=== Examples
|
47
|
+
|
48
|
+
#Set the SEO global title
|
49
|
+
#Seo.global.title = "SEO Title"
|
50
|
+
|
51
|
+
#Grab that child industry title
|
52
|
+
industry.seo.title
|
53
|
+
# => 'SEO Title'
|
54
|
+
|
55
|
+
#Grab the client title
|
56
|
+
client.seo.title
|
57
|
+
# => 'SEO Title'
|
58
|
+
|
59
|
+
#Change the industry title
|
60
|
+
industry.seo.title = 'Industry Title'
|
61
|
+
|
62
|
+
#Check the client
|
63
|
+
client.seo.title
|
64
|
+
# => 'Industry Title'
|
65
|
+
|
66
|
+
#Grab all the Keys for the client
|
67
|
+
client.seo.all
|
68
|
+
# => {:title=>"Industry Title"}
|
69
|
+
|
70
|
+
#Grab all the non-inherited keys from the client
|
71
|
+
client.seo.all(false)
|
72
|
+
# => {}
|
73
|
+
|
74
|
+
|
75
|
+
== Note on Patches/Pull Requests
|
76
|
+
|
77
|
+
* Fork the project.
|
78
|
+
* Make your feature addition or bug fix.
|
79
|
+
* Add tests for it. This is important so I don't break it in a
|
80
|
+
future version unintentionally.
|
81
|
+
* Commit, do not mess with rakefile, version, or history.
|
82
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
83
|
+
* Send me a pull request. Bonus points for topic branches.
|
84
|
+
|
85
|
+
== Copyright
|
86
|
+
|
87
|
+
Copyright (c) 2010 Mark Turner. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "has_inherited"
|
8
|
+
gem.summary = "Easily share variables between Rails models with inheritance."
|
9
|
+
gem.description = "The intention of this library is to make it easy to inherit particular variables between models in rails apps. We start with a parent model that will function as a pseudo-polymorphic association for children objects."
|
10
|
+
gem.email = "mark@amerine.net"
|
11
|
+
gem.homepage = "http://github.com/amerine/has_inherited"
|
12
|
+
gem.authors = ["Mark Turner"]
|
13
|
+
gem.add_development_dependency "bacon", ">= 0"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:spec) do |spec|
|
23
|
+
spec.libs << 'lib' << 'spec'
|
24
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
25
|
+
spec.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |spec|
|
31
|
+
spec.libs << 'spec'
|
32
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
33
|
+
spec.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :spec => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :spec
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "has_inherited #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{has_inherited}
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Mark Turner"]
|
12
|
+
s.date = %q{2010-11-17}
|
13
|
+
s.description = %q{The intention of this library is to make it easy to inherit particular variables between models in rails apps. We start with a parent model that will function as a pseudo-polymorphic association for children objects.}
|
14
|
+
s.email = %q{mark@amerine.net}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"has_inherited.gemspec",
|
27
|
+
"lib/has_inherited.rb",
|
28
|
+
"spec/has_inherited_spec.rb",
|
29
|
+
"spec/spec_helper.rb"
|
30
|
+
]
|
31
|
+
s.homepage = %q{http://github.com/amerine/has_inherited}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.7}
|
35
|
+
s.summary = %q{Easily share variables between Rails models with inheritance.}
|
36
|
+
s.test_files = [
|
37
|
+
"spec/has_inherited_spec.rb",
|
38
|
+
"spec/spec_helper.rb"
|
39
|
+
]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_development_dependency(%q<bacon>, [">= 0"])
|
47
|
+
else
|
48
|
+
s.add_dependency(%q<bacon>, [">= 0"])
|
49
|
+
end
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<bacon>, [">= 0"])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module HasInherited
|
2
|
+
def self.included(base)
|
3
|
+
base.extend ClassMethods
|
4
|
+
end # self.included
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def is_inheritable(*name)
|
8
|
+
attr = name.shift || :global
|
9
|
+
assoc = "_#{attr}"
|
10
|
+
|
11
|
+
named_scope assoc.to_sym,
|
12
|
+
:conditions => 'inheritable_id IS NULL AND inheritable_type IS NULL'
|
13
|
+
|
14
|
+
(class << self; self; end).instance_eval do
|
15
|
+
define_method attr do
|
16
|
+
instance_variable_get(:"@#{attr.to_s}") || instance_variable_set(:"@#{attr.to_s}", InheritAccessor.new(self, assoc.to_sym, nil))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
belongs_to :inheritable, :polymorphic => true
|
21
|
+
include HasInherited::InstanceMethods
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_inherited(*opts)
|
25
|
+
options = opts.extract_options!
|
26
|
+
attr = opts.shift || 'inheritable'
|
27
|
+
assoc = "_#{attr}"
|
28
|
+
class_name = options[:inherit_class] || 'Seo'
|
29
|
+
|
30
|
+
has_many assoc.to_sym, :class_name => class_name, :as => :inheritable, :dependent => :destroy
|
31
|
+
|
32
|
+
define_method attr do
|
33
|
+
instance_variable_get(:"@#{attr.to_s}") || instance_variable_set(:"@#{attr.to_s}", InheritAccessor.new(self, assoc.to_sym, options[:from]))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end # ClassMethods
|
37
|
+
|
38
|
+
class InheritAccessor
|
39
|
+
# In 1.9 I would use a BasicObject here. A conditional check wouldn't hurt.
|
40
|
+
instance_methods.each {|m| undef_method m unless m.to_s =~ /(^__|send|inject)/}
|
41
|
+
|
42
|
+
def initialize(owner, assoc, heritage)
|
43
|
+
@owner = owner
|
44
|
+
@assoc = @owner.send(assoc)
|
45
|
+
if heritage.kind_of? Array
|
46
|
+
@parent = heritage.first
|
47
|
+
@parent_accessor = heritage.second
|
48
|
+
else
|
49
|
+
@parent = heritage
|
50
|
+
end
|
51
|
+
|
52
|
+
if @parent && @parent_accessor.nil?
|
53
|
+
if @parent.kind_of? Class
|
54
|
+
@parent_accessor = :global
|
55
|
+
else
|
56
|
+
@parent_accessor = :inheritable
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def [](attribute)
|
62
|
+
attr_value = find_attr(attribute).try(:value)
|
63
|
+
if attr_value.nil? && has_parent?
|
64
|
+
return parent.__send__(:[], attribute)
|
65
|
+
else
|
66
|
+
return attr_value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def []=(attribute, value)
|
71
|
+
attr = find_attr(attribute)
|
72
|
+
if value.nil?
|
73
|
+
attr.delete if attribute
|
74
|
+
else
|
75
|
+
if attr.nil?
|
76
|
+
if @owner.respond_to?(:new_record?) && @owner.new_record?
|
77
|
+
attr = @assoc.build(:name => attribute.to_s, :value => value)
|
78
|
+
else
|
79
|
+
attr = @assoc.create(:name => attribute.to_s, :value => value)
|
80
|
+
end
|
81
|
+
else
|
82
|
+
attr.update_attributes(:value => value)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def all(inherited = true)
|
88
|
+
all_values = {}
|
89
|
+
@assoc.all.each {|inherited| all_values[inherited.name.to_sym] = inherited.value}
|
90
|
+
if inherited
|
91
|
+
parent_proxy = parent
|
92
|
+
while parent_proxy
|
93
|
+
parent_proxy_hash = parent_proxy.__send__(:all, false)
|
94
|
+
all_values.reverse_merge! parent_proxy_hash
|
95
|
+
parent_proxy = parent_proxy.__send__(:parent)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
all_values
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def parent
|
104
|
+
if has_parent?
|
105
|
+
parent = @parent.is_a?(Class) ? @parent : @owner.__send__(@parent)
|
106
|
+
parent.__send__(@parent_accessor)
|
107
|
+
else
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def find_attr(attr)
|
113
|
+
@assoc.first(:conditions => ['name = ?', attr.to_s])
|
114
|
+
end
|
115
|
+
|
116
|
+
def has_parent?
|
117
|
+
!! @parent
|
118
|
+
end
|
119
|
+
|
120
|
+
def method_missing(symbol, *args)
|
121
|
+
name = symbol.to_s
|
122
|
+
if name =~ /=$/
|
123
|
+
self[name.gsub(/=$/, '')] = args.first
|
124
|
+
else
|
125
|
+
self[name]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
module InstanceMethods
|
131
|
+
def value
|
132
|
+
case self[:value_type]
|
133
|
+
when 'String'
|
134
|
+
self[:value]
|
135
|
+
when 'Fixnum', 'Bignum'
|
136
|
+
Integer(self[:value])
|
137
|
+
when 'Float'
|
138
|
+
Float(self[:value])
|
139
|
+
when 'Symbol'
|
140
|
+
self[:value].to_sym
|
141
|
+
when 'TrueClass'
|
142
|
+
true
|
143
|
+
when 'FalseClass'
|
144
|
+
false
|
145
|
+
when 'Time'
|
146
|
+
Time.parse(self[:value])
|
147
|
+
when 'Date'
|
148
|
+
Date.parse(self[:value])
|
149
|
+
when 'DateTime'
|
150
|
+
DateTime.parse(self[:value])
|
151
|
+
else
|
152
|
+
self[:value]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def value=(new_value)
|
157
|
+
if new_value.nil?
|
158
|
+
self[:value] = self.value_type = nil
|
159
|
+
else
|
160
|
+
new_type = new_value.class.to_s
|
161
|
+
case new_type
|
162
|
+
when 'Symbol'
|
163
|
+
new_value = new_value.to_s
|
164
|
+
when 'Fixnum', 'Float', 'Bignum', 'TrueClass', 'FalseClass'
|
165
|
+
new_value = new_value.to_s
|
166
|
+
when 'Time', 'Date', 'DateTime'
|
167
|
+
new_value = new_value.to_s(:rfc822)
|
168
|
+
end
|
169
|
+
self[:value] = new_value
|
170
|
+
self.value_type = new_type
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
ActiveRecord::Base.send(:include, HasInherited)
|
@@ -0,0 +1,203 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
class Seo < ActiveRecord::Base
|
5
|
+
is_inheritable
|
6
|
+
end
|
7
|
+
|
8
|
+
class Industry < ActiveRecord::Base
|
9
|
+
has_inherited :seo, :from => Seo
|
10
|
+
has_many :clients
|
11
|
+
end
|
12
|
+
|
13
|
+
class Client < ActiveRecord::Base
|
14
|
+
belongs_to :industry
|
15
|
+
has_many :stores
|
16
|
+
has_inherited :seo, :from => [:industry, :seo], :inherit_class => 'Seo'
|
17
|
+
end
|
18
|
+
|
19
|
+
class Store < ActiveRecord::Base
|
20
|
+
belongs_to :client
|
21
|
+
has_inherited :seo, :from => [:client, :seo], :inherit_class => 'Seo'
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "HasInherited" do
|
25
|
+
|
26
|
+
before do
|
27
|
+
ActiveRecord::Base.logger = Logger.new('test.log')
|
28
|
+
ActiveRecord::Base.logger.level = Logger::DEBUG
|
29
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
30
|
+
ActiveRecord::Schema.suppress_messages do
|
31
|
+
ActiveRecord::Schema.define(:version => 1) do
|
32
|
+
create_table :seos do |t|
|
33
|
+
t.integer :inheritable_id
|
34
|
+
t.string :inheritable_type
|
35
|
+
t.string :name, :limit => 50, :null => false
|
36
|
+
t.string :value
|
37
|
+
t.string :value_type
|
38
|
+
end
|
39
|
+
|
40
|
+
create_table :industries do |t|
|
41
|
+
t.name :string
|
42
|
+
t.timestamps
|
43
|
+
end
|
44
|
+
|
45
|
+
create_table :clients do |t|
|
46
|
+
t.name :string
|
47
|
+
t.references :industry
|
48
|
+
t.timestamps
|
49
|
+
end
|
50
|
+
|
51
|
+
create_table :stores do |t|
|
52
|
+
t.name :string
|
53
|
+
t.references :client
|
54
|
+
t.timestamps
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
after do
|
62
|
+
ActiveRecord::Base.connection.tables.each do |t|
|
63
|
+
ActiveRecord::Base.connection.drop_table(t)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should have a value' do
|
68
|
+
s = Seo.new
|
69
|
+
s.value = "Some Title"
|
70
|
+
s.value.should.equal "Some Title"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "has the ability to set global variables" do
|
74
|
+
Seo.global.title = "Title"
|
75
|
+
Seo.global.title.should.equal "Title"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should be able to set variables" do
|
79
|
+
Seo.global.title = "Title"
|
80
|
+
industry = Industry.create
|
81
|
+
industry.seo.title.should.equal "Title"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should work with two levels of nesting" do
|
85
|
+
Seo.global.title = "SEO Title"
|
86
|
+
industry = Industry.create
|
87
|
+
client = industry.clients.create
|
88
|
+
client.seo.title.should.equal 'SEO Title'
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should work with three levels of nesting" do
|
92
|
+
Seo.global.title = "SEO Title"
|
93
|
+
industry = Industry.create
|
94
|
+
client = industry.clients.create
|
95
|
+
client.seo.title.should.equal "SEO Title"
|
96
|
+
client.seo.title = "Client Title"
|
97
|
+
client.seo.title.should.equal "Client Title"
|
98
|
+
end
|
99
|
+
|
100
|
+
it "Should allow you to see all the custom values" do
|
101
|
+
Seo.global.title = "SEO Title"
|
102
|
+
Seo.global.keywords = "Awesome, Words, Are, Awesome"
|
103
|
+
Seo.global.luke = "Luke"
|
104
|
+
industry = Industry.create
|
105
|
+
industry.seo.luke = "Luke 2"
|
106
|
+
industry.seo.luke = nil
|
107
|
+
client = industry.clients.create
|
108
|
+
client.seo.title = "Client Title"
|
109
|
+
client.seo.keywords = "Awesome"
|
110
|
+
client.seo.all.size.should.equal 3
|
111
|
+
puts client.seo.all.inspect
|
112
|
+
client.seo.luke.should.equal 'Luke'
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
it "should allow you to not include parent objects when grabbing all" do
|
117
|
+
Seo.global.title = "SEO Title"
|
118
|
+
|
119
|
+
industry = Industry.create
|
120
|
+
industry.seo.title = "Industry Title"
|
121
|
+
|
122
|
+
client = industry.clients.create
|
123
|
+
client.seo.title = "Client Title"
|
124
|
+
|
125
|
+
store = client.stores.create
|
126
|
+
store.seo.title = "Store Title"
|
127
|
+
|
128
|
+
store.seo.all(false).size.should.equal 1
|
129
|
+
client.seo.all(false).size.should.equal 1
|
130
|
+
industry.seo.all(false).size.should.equal 1
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should work with four levels of nesting" do
|
134
|
+
Seo.global.title = "SEO Title"
|
135
|
+
industry = Industry.create
|
136
|
+
client = industry.clients.create
|
137
|
+
store = client.stores.create
|
138
|
+
store.seo.title.should.equal "SEO Title"
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "Type Conversion" do
|
142
|
+
it "should store and retrieve Strings" do
|
143
|
+
Seo.global.title = "Title"
|
144
|
+
Seo.global.title.class.should.equal String
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should store and retrieve Fixnums" do
|
148
|
+
Seo.global.number = 42
|
149
|
+
Seo.global.number.class.should.equal Fixnum
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should store and retrieve Bignums" do
|
153
|
+
Seo.global.number = 123456789101112131415161718123
|
154
|
+
Seo.global.number.class.should.equal Bignum
|
155
|
+
Seo.global.number.should.equal 123456789101112131415161718123
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should store and retrieve Floats" do
|
159
|
+
Seo.global.float = 1.2345678910
|
160
|
+
Seo.global.float.class.should.equal Float
|
161
|
+
Seo.global.float.should.equal 1.2345678910
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should store and retrieve Symbols" do
|
165
|
+
Seo.global.symbol = :symbol
|
166
|
+
Seo.global.symbol.class.should.equal Symbol
|
167
|
+
Seo.global.symbol.should.equal :symbol
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should store and retrieve True" do
|
171
|
+
Seo.global.true = true
|
172
|
+
Seo.global.true.class.should.equal TrueClass
|
173
|
+
Seo.global.true.should.equal true
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should store and retrieve False" do
|
177
|
+
Seo.global.false = false
|
178
|
+
Seo.global.false.class.should.equal FalseClass
|
179
|
+
Seo.global.false.should.equal false
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should store and retrieve Time" do
|
183
|
+
time = Time.now
|
184
|
+
Seo.global.time = time
|
185
|
+
Seo.global.time.class.should.equal Time
|
186
|
+
Seo.global.time.to_s.should.equal time.to_s
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should store and retrieve Dates" do
|
190
|
+
date = Date.today
|
191
|
+
Seo.global.date = date
|
192
|
+
Seo.global.date.class.should.equal Date
|
193
|
+
Seo.global.date.should.equal date
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should store and retrieve DateTime" do
|
197
|
+
datetime = DateTime.now
|
198
|
+
Seo.global.datetime = datetime
|
199
|
+
Seo.global.datetime.class.should.equal DateTime
|
200
|
+
Seo.global.datetime.to_s.should.equal datetime.to_s
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: has_inherited
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Mark Turner
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-17 00:00:00 -08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: bacon
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
description: The intention of this library is to make it easy to inherit particular variables between models in rails apps. We start with a parent model that will function as a pseudo-polymorphic association for children objects.
|
36
|
+
email: mark@amerine.net
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.rdoc
|
44
|
+
files:
|
45
|
+
- .document
|
46
|
+
- .gitignore
|
47
|
+
- LICENSE
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
51
|
+
- has_inherited.gemspec
|
52
|
+
- lib/has_inherited.rb
|
53
|
+
- spec/has_inherited_spec.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://github.com/amerine/has_inherited
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --charset=UTF-8
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.3.7
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Easily share variables between Rails models with inheritance.
|
89
|
+
test_files:
|
90
|
+
- spec/has_inherited_spec.rb
|
91
|
+
- spec/spec_helper.rb
|