has-relationship 0.0.2
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/README.rdoc +0 -0
- data/Rakefile +59 -0
- data/VERSION +1 -0
- data/lib/generators/has_relationship/migration/migration_generator.rb +32 -0
- data/lib/generators/has_relationship/migration/templates/active_record/migration.rb +21 -0
- data/lib/has-relationship.rb +12 -0
- data/lib/has_relationship/has_relationship.rb +98 -0
- data/lib/has_relationship/relationship.rb +11 -0
- data/rails/init.rb +1 -0
- metadata +75 -0
data/README.rdoc
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
begin
|
2
|
+
# Rspec 1.3.0
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
|
5
|
+
desc 'Default: run specs'
|
6
|
+
task :default => :spec
|
7
|
+
Spec::Rake::SpecTask.new do |t|
|
8
|
+
t.spec_files = FileList["spec/**/*_spec.rb"]
|
9
|
+
end
|
10
|
+
|
11
|
+
Spec::Rake::SpecTask.new('rcov') do |t|
|
12
|
+
t.spec_files = FileList["spec/**/*_spec.rb"]
|
13
|
+
t.rcov = true
|
14
|
+
t.rcov_opts = ['--exclude', 'spec']
|
15
|
+
end
|
16
|
+
|
17
|
+
rescue LoadError
|
18
|
+
# Rspec 2.0
|
19
|
+
require 'rspec/core/rake_task'
|
20
|
+
|
21
|
+
desc 'Default: run specs'
|
22
|
+
task :default => :spec
|
23
|
+
Rspec::Core::RakeTask.new do |t|
|
24
|
+
t.pattern = "spec/**/*_spec.rb"
|
25
|
+
end
|
26
|
+
|
27
|
+
Rspec::Core::RakeTask.new('rcov') do |t|
|
28
|
+
t.pattern = "spec/**/*_spec.rb"
|
29
|
+
t.rcov = true
|
30
|
+
t.rcov_opts = ['--exclude', 'spec']
|
31
|
+
end
|
32
|
+
|
33
|
+
rescue LoadError
|
34
|
+
puts "Rspec not available. Install it with: gem install rspec"
|
35
|
+
end
|
36
|
+
|
37
|
+
namespace 'rails2.3' do
|
38
|
+
task :spec do
|
39
|
+
gemfile = File.join(File.dirname(__FILE__), 'lib', 'has_relationship', 'compatibility', 'Gemfile')
|
40
|
+
ENV['BUNDLE_GEMFILE'] = gemfile
|
41
|
+
Rake::Task['spec'].invoke
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
begin
|
46
|
+
require 'jeweler'
|
47
|
+
Jeweler::Tasks.new do |gemspec|
|
48
|
+
gemspec.name = "has-relationship"
|
49
|
+
gemspec.summary = "has_relationship is an easy way to instantly create an association between any two database tables"
|
50
|
+
gemspec.description = "With has_relationship, you can instantly create an association between any two database tables."
|
51
|
+
gemspec.email = "hunterae@gmail.com"
|
52
|
+
gemspec.homepage = "http://github.com/hunterae/has_relationship"
|
53
|
+
gemspec.authors = ["Andrew Hunter"]
|
54
|
+
gemspec.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"] - FileList["**/*.log"]
|
55
|
+
end
|
56
|
+
Jeweler::GemcutterTasks.new
|
57
|
+
rescue LoadError
|
58
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
59
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
|
3
|
+
module HasRelationship
|
4
|
+
class MigrationGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
desc "Generates migration for Tag and Tagging models"
|
8
|
+
|
9
|
+
def self.orm
|
10
|
+
Rails::Generators.options[:rails][:orm]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.source_root
|
14
|
+
File.join(File.dirname(__FILE__), 'templates', (orm.to_s unless orm.class.eql?(String)) )
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.orm_has_migration?
|
18
|
+
[:active_record].include? orm
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.next_migration_number(path)
|
22
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_migration_file
|
26
|
+
if self.class.orm_has_migration?
|
27
|
+
migration_template 'migration.rb', 'db/migrate/has_relationship_migration'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class HasRelationshipMigration < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :relationships do |t|
|
4
|
+
t.column :relation1_id, :integer
|
5
|
+
t.column :relation1_type, :string
|
6
|
+
|
7
|
+
t.column :relation2_id, :integer
|
8
|
+
t.column :relation2_type, :string
|
9
|
+
|
10
|
+
t.column :relationship, :string
|
11
|
+
|
12
|
+
t.column :created_at, :datetime
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :taggings, [:relation1_id, :relation1_type, :relation2_id, :relation2_type, :relationship]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :relationships
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "active_record"
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
|
5
|
+
require "has_relationship/has_relationship"
|
6
|
+
require "has_relationship/relationship"
|
7
|
+
|
8
|
+
$LOAD_PATH.shift
|
9
|
+
|
10
|
+
if defined?(ActiveRecord::Base)
|
11
|
+
ActiveRecord::Base.extend HasRelationship::Base
|
12
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module HasRelationship
|
2
|
+
module Base
|
3
|
+
def has_relationship(types, options={})
|
4
|
+
types = [types] unless types.kind_of?(Array)
|
5
|
+
|
6
|
+
types.each do |type|
|
7
|
+
class_name = type.to_s.classify
|
8
|
+
|
9
|
+
# default relationship: Class1_Class2, where Class1 is the class of this class,
|
10
|
+
# Class2 is the class of that this class has a relationship with
|
11
|
+
relationship = "#{self.to_s}_#{class_name}"
|
12
|
+
|
13
|
+
unless options[:singular].present?
|
14
|
+
as = options[:as] ? options[:as].to_s : type.to_s
|
15
|
+
|
16
|
+
options[:singular] = (as.pluralize != as)
|
17
|
+
end
|
18
|
+
|
19
|
+
if options[:as]
|
20
|
+
resource_name = options[:as].to_sym
|
21
|
+
relationship = "#{self.to_s}_#{options[:as].to_s.classify}"
|
22
|
+
elsif options[:singular]
|
23
|
+
resource_name = type.to_s.tableize.singularize.to_sym
|
24
|
+
else
|
25
|
+
resource_name = type.to_s.tableize.to_sym
|
26
|
+
end
|
27
|
+
|
28
|
+
relationship = options[:relationship] if options[:relationship]
|
29
|
+
relationship_through = options[:singular] ? "relationship_through_#{relationship.to_s.tableize.singularize}".to_sym : "relationship_through_#{relationship.to_s.tableize}".to_sym
|
30
|
+
|
31
|
+
HasRelationship::Relationship.class_eval do
|
32
|
+
belongs_to "relation2_#{class_name.downcase}".to_sym, :class_name => class_name, :foreign_key => "relation2_id"
|
33
|
+
|
34
|
+
before_validation do
|
35
|
+
self.relation2 = self.send("relation2_#{class_name.downcase}") unless self.relation2.present? or self.send("relation2_#{class_name.downcase}").nil?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class_eval do
|
40
|
+
if options[:singular]
|
41
|
+
has_one relationship_through, :as => :relation1, :dependent => :destroy, :class_name => "HasRelationship::Relationship", :conditions => {:relationship => relationship}
|
42
|
+
has_one resource_name, :through => relationship_through, :class_name => class_name, :source => "relation2_#{class_name.downcase}".to_s, :conditions => ["relationships.relation2_type = ? and relationships.relationship = ?", class_name, relationship]
|
43
|
+
else
|
44
|
+
has_many relationship_through, :as => :relation1, :dependent => :destroy, :class_name => "HasRelationship::Relationship", :conditions => {:relationship => relationship}
|
45
|
+
has_many resource_name, :through => relationship_through, :class_name => class_name, :source => "relation2_#{class_name.downcase}".to_sym, :conditions => ["relationships.relation2_type = ? and relationships.relationship = ?", class_name, relationship]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_inverse_relationship(types, options={})
|
52
|
+
types = [types] unless types.kind_of?(Array)
|
53
|
+
|
54
|
+
types.each do |type|
|
55
|
+
class_name = type.to_s.classify
|
56
|
+
|
57
|
+
# default relationship: Class2_Class1, where Class1 is the class of this class,
|
58
|
+
# Class2 is the class of that this class has a relationship with
|
59
|
+
relationship = "#{class_name}_#{self.to_s}"
|
60
|
+
|
61
|
+
unless options[:singular].present?
|
62
|
+
as = options[:as] ? options[:as].to_s : type.to_s
|
63
|
+
options[:singular] = (as.pluralize != as)
|
64
|
+
end
|
65
|
+
|
66
|
+
if options[:as]
|
67
|
+
resource_name = options[:as].to_sym
|
68
|
+
relationship = "#{options[:as].to_s.classify}_#{self.to_s}"
|
69
|
+
elsif options[:singular]
|
70
|
+
resource_name = type.to_s.tableize.singularize.to_sym
|
71
|
+
else
|
72
|
+
resource_name = type.to_s.tableize.to_sym
|
73
|
+
end
|
74
|
+
|
75
|
+
relationship = options[:relationship] if options[:relationship]
|
76
|
+
relationship_through = options[:singular] ? "inverse_relationship_through_#{relationship.to_s.tableize.singularize}".to_sym : "inverse_relationship_through_#{relationship.to_s.tableize}".to_sym
|
77
|
+
|
78
|
+
HasRelationship::Relationship.class_eval do
|
79
|
+
belongs_to "relation1_#{class_name.downcase}".to_sym, :class_name => class_name, :foreign_key => "relation1_id"
|
80
|
+
|
81
|
+
before_validation do
|
82
|
+
self.relation1 = self.send("relation1_#{class_name.downcase}") unless self.relation1.present? or self.send("relation1_#{class_name.downcase}").nil?
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class_eval do
|
87
|
+
if options[:singular]
|
88
|
+
has_one relationship_through, :as => :relation2, :dependent => :destroy, :class_name => "HasRelationship::Relationship", :conditions => {:relationship => relationship}
|
89
|
+
has_one resource_name, :through => relationship_through, :class_name => class_name, :source => "relation1_#{class_name.downcase}".to_sym, :conditions => ["relationships.relation1_type = ? and relationships.relationship = ?", class_name, relationship]
|
90
|
+
else
|
91
|
+
has_many relationship_through, :as => :relation2, :dependent => :destroy, :class_name => "HasRelationship::Relationship", :conditions => {:relationship => relationship}
|
92
|
+
has_many resource_name, :through => relationship_through, :class_name => class_name, :source => "relation1_#{class_name.downcase}".to_sym, :conditions => ["relationships.relation1_type = ? and relationships.relationship = ?", class_name, relationship]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module HasRelationship
|
2
|
+
class Relationship < ::ActiveRecord::Base #:nodoc:
|
3
|
+
|
4
|
+
belongs_to :relation1, :polymorphic => true
|
5
|
+
belongs_to :relation2, :polymorphic => true
|
6
|
+
|
7
|
+
before_create do
|
8
|
+
self.relationship = self.relation1.class.to_s + "_" + self.relation2.class.to_s if self.relationship.blank?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'has-relationship'
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: has-relationship
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Andrew Hunter
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-03-22 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: With has_relationship, you can instantly create an association between any two database tables.
|
23
|
+
email: hunterae@gmail.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.rdoc
|
30
|
+
files:
|
31
|
+
- README.rdoc
|
32
|
+
- Rakefile
|
33
|
+
- VERSION
|
34
|
+
- lib/generators/has_relationship/migration/migration_generator.rb
|
35
|
+
- lib/generators/has_relationship/migration/templates/active_record/migration.rb
|
36
|
+
- lib/has-relationship.rb
|
37
|
+
- lib/has_relationship/has_relationship.rb
|
38
|
+
- lib/has_relationship/relationship.rb
|
39
|
+
- rails/init.rb
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://github.com/hunterae/has_relationship
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
hash: 3
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
64
|
+
segments:
|
65
|
+
- 0
|
66
|
+
version: "0"
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.7
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: has_relationship is an easy way to instantly create an association between any two database tables
|
74
|
+
test_files: []
|
75
|
+
|