Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
git-svn-id: svn+ssh://svn0.sea.apvio.net/home/rwl4/inherits_from@1 bd10a536-b517-0410-99c0-c9a68740b5c0
- Loading branch information
rwl4
committed
Jul 3, 2006
0 parents
commit 7e682f9
Showing
11 changed files
with
150 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
InheritsFrom | ||
============ | ||
|
||
Allows class inheritance with ActiveRecord. | ||
|
||
It is very basic at the moment, and might even be fundamentally flawed. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
require 'rake' | ||
require 'rake/testtask' | ||
require 'rake/rdoctask' | ||
|
||
desc 'Default: run unit tests.' | ||
task :default => :test | ||
|
||
desc 'Test the inherits_from plugin.' | ||
Rake::TestTask.new(:test) do |t| | ||
t.libs << 'lib' | ||
t.pattern = 'test/**/*_test.rb' | ||
t.verbose = true | ||
end | ||
|
||
desc 'Generate documentation for the inherits_from plugin.' | ||
Rake::RDocTask.new(:rdoc) do |rdoc| | ||
rdoc.rdoc_dir = 'rdoc' | ||
rdoc.title = 'InheritsFrom' | ||
rdoc.options << '--line-numbers' << '--inline-source' | ||
rdoc.rdoc_files.include('README') | ||
rdoc.rdoc_files.include('lib/**/*.rb') | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
require 'inherits_from' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
require 'active_record' | ||
|
||
# +inherits_from+ is an +ActiveRecord+ plugin designed to allow simple multiple table (class) inheritance. | ||
# | ||
# Example: | ||
# class Product < ActiveRecord::Base | ||
# inherits_from :product | ||
# end | ||
# | ||
# class Book < ActiveRecord::Base | ||
# inherits_from :product | ||
# end | ||
# | ||
# class Video < ActiveRecord::Base | ||
# inherits_from :product | ||
# end | ||
# | ||
# book = Book.find(1) | ||
# book.name => "Agile Development with Rails" | ||
# book.author => "Dave Thomas" | ||
# | ||
# video = Video.find(2) | ||
# book.name => "Twilight Zone Season 1" | ||
# book.actors => "Rod Serling" | ||
|
||
class ActiveRecord::Base | ||
attr_reader :reflection | ||
|
||
# Creates an inheritance association and generates proxy methods in the inherited object for easy access to the parent. | ||
# Currently, the options are ignored. | ||
# | ||
# Example: | ||
# class Book < ActiveRecord::Base | ||
# inherits_from :product | ||
# end | ||
def self.inherits_from(association_id, options = {}) | ||
belongs_to association_id | ||
|
||
reflection = create_reflection(:belongs_to, association_id, options, self) | ||
|
||
association_class = Object.const_get(reflection.class_name) | ||
|
||
inherited_column_names = association_class.column_names.reject { |c| self.column_names.grep(c).length > 0 || c == "type"} | ||
|
||
inherited_column_names.each { |name| alias_associated_attr(association_id, name) } | ||
|
||
before_callback = <<-end_eval | ||
init_inherited("#{association_id}") | ||
instance_variable_get("@#{association_id}").save | ||
end_eval | ||
|
||
before_create(before_callback) | ||
before_update(before_callback) | ||
end | ||
|
||
# Creates a proxy accessor method for an inherited object. | ||
def self.alias_associated_attr(association_id, name) | ||
define_method(name) do | ||
init_inherited_assoc(association_id) | ||
klass = send(association_id) | ||
|
||
klass.send(name) | ||
end | ||
|
||
define_method("#{name}=") do |new_value| | ||
init_inherited_assoc(association_id) | ||
klass = send(association_id) | ||
|
||
klass.send("#{name}=", new_value) | ||
end | ||
end | ||
|
||
private | ||
# Ensures that there is an association to access, if not, creates one. | ||
def init_inherited_assoc(association_id) | ||
if new_record? and instance_variable_get("@#{association_id}").nil? | ||
send("build_#{association_id}") | ||
instance_variable_get("@#{association_id}").type = self.class.to_s | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
class Book < ActiveRecord::Base | ||
inherits_from :product | ||
|
||
validates_presence_of :name, :price, :pages | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
agile_book: | ||
author: Dave Thomas | ||
product_id: 1 | ||
id: 1 | ||
pages: 300 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
class Product < ActiveRecord::Base | ||
validates_presence_of :name | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
agile_book: | ||
name: Agile Web Development with Rails | ||
price: 2995 | ||
type: Book | ||
id: 1 | ||
twilight_video: | ||
name: Twilight Zone Season 1 | ||
price: 8945 | ||
type: Video | ||
id: 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
class Video < ActiveRecord::Base | ||
inherits_from :product | ||
|
||
validates_presence_of :name, :price, :minutes, :starring | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
twilight_video: | ||
minutes: 490 | ||
product_id: 2 | ||
id: 1 | ||
starring: Rod Serling |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
require 'test/unit' | ||
|
||
class InheritsFromTest < Test::Unit::TestCase | ||
def test_code_needs_to_be_written | ||
flunk "Anyone care to write some tests for me? ActiveRecord tests are painful." | ||
end | ||
end |