piggyback 0.1.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/Manifest +6 -0
- data/README.rdoc +0 -0
- data/Rakefile +14 -0
- data/lib/piggyback.rb +96 -0
- data/piggyback.gemspec +29 -0
- data/spec/piggyback_spec.rb +34 -0
- data/spec/spec_helper.rb +49 -0
- metadata +68 -0
data/Manifest
ADDED
data/README.rdoc
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('piggyback', '0.1.0') do |p|
|
6
|
+
p.description = "Piggyback associated models with ActiveRecord"
|
7
|
+
p.url = "http://github.com/juni0r/piggyback"
|
8
|
+
p.author = "Andreas Korth"
|
9
|
+
p.email = "andreas.korth@gmail.com"
|
10
|
+
p.ignore_pattern = ["tmp/*", "log/*", "Gemfile", "Gemfile.lock"]
|
11
|
+
p.development_dependencies = []
|
12
|
+
end
|
13
|
+
|
14
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/lib/piggyback.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
module Piggyback
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do |model|
|
5
|
+
model.class_inheritable_hash :piggyback_associations
|
6
|
+
model.piggyback_associations = {}
|
7
|
+
|
8
|
+
model.class_inheritable_hash :piggyback_attributes
|
9
|
+
model.piggyback_attributes = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
class Association
|
13
|
+
|
14
|
+
attr_reader :reflection, :attributes
|
15
|
+
|
16
|
+
def initialize(*args)
|
17
|
+
@reflection, @attributes = *args
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
|
23
|
+
def piggy(*associations)
|
24
|
+
columns = piggyback_attributes.values_at(*associations).map do |association|
|
25
|
+
table_name = association.reflection.klass.quoted_table_name
|
26
|
+
association.attributes.map do |attribute, mapping|
|
27
|
+
if attribute != mapping
|
28
|
+
"#{table_name}.#{connection.quote_column_name(mapping)} AS #{attribute}"
|
29
|
+
else
|
30
|
+
"#{table_name}.#{connection.quote_column_name(attribute)}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
columns.flatten!
|
35
|
+
columns.unshift("#{quoted_table_name}.*") unless scoped.select_values.any?
|
36
|
+
select(columns.join(', ')).joins(*associations)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def piggyback(association, *unmapped_attributes)
|
41
|
+
|
42
|
+
reflection = reflect_on_association(association.to_sym)
|
43
|
+
|
44
|
+
unless reflection
|
45
|
+
raise ArgumentError.new("#{self.class.name} has no association named '#{association}'.")
|
46
|
+
end
|
47
|
+
|
48
|
+
unless [:belongs_to, :has_one].include?(reflection.macro)
|
49
|
+
raise ArgumentError.new("Only belongs_to and has_many associations can be used for piggybacking.")
|
50
|
+
end
|
51
|
+
|
52
|
+
mapped_attributes = unmapped_attributes.extract_options!
|
53
|
+
unmapped_attributes.concat(Array(mapped_attributes.delete(:attributes)))
|
54
|
+
|
55
|
+
attributes = {}
|
56
|
+
|
57
|
+
unmapped_attributes.flatten.each do |attr_name|
|
58
|
+
attr_name = attr_name.to_s
|
59
|
+
attributes[attr_name] = attr_name
|
60
|
+
end
|
61
|
+
|
62
|
+
mapped_attributes.each do |attr_name, mapping|
|
63
|
+
attributes[attr_name.to_s] = mapping.to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
association = Association.new(reflection, attributes)
|
67
|
+
|
68
|
+
piggyback_attributes[reflection.name] = association
|
69
|
+
|
70
|
+
attributes.each do |attr_name, mapping|
|
71
|
+
piggyback_associations[attr_name] = association
|
72
|
+
define_method attr_name do
|
73
|
+
if @attributes.has_key?(attr_name)
|
74
|
+
read_attribute(attr_name)
|
75
|
+
else
|
76
|
+
send(reflection.name).send(mapping)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
columns_hash.default_proc = lambda do |hash, attr_name|
|
82
|
+
if association = piggyback_associations[attr_name]
|
83
|
+
association.reflection.klass.columns_hash[attr_name]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
serialized_attributes.default_proc = lambda do |hash, attr_name|
|
88
|
+
if association = piggyback_associations[attr_name]
|
89
|
+
association.reflection.klass.serialized_attributes[attr_name]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
ActiveRecord::Base.send(:include, Piggyback)
|
data/piggyback.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{piggyback}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Andreas Korth"]
|
9
|
+
s.date = %q{2011-03-20}
|
10
|
+
s.description = %q{Piggyback associated models with ActiveRecord}
|
11
|
+
s.email = %q{andreas.korth@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["README.rdoc", "lib/piggyback.rb"]
|
13
|
+
s.files = ["README.rdoc", "Rakefile", "lib/piggyback.rb", "spec/piggyback_spec.rb", "spec/spec_helper.rb", "Manifest", "piggyback.gemspec"]
|
14
|
+
s.homepage = %q{http://github.com/juni0r/piggyback}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Piggyback", "--main", "README.rdoc"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{piggyback}
|
18
|
+
s.rubygems_version = %q{1.5.2}
|
19
|
+
s.summary = %q{Piggyback associated models with ActiveRecord}
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
s.specification_version = 3
|
23
|
+
|
24
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
|
+
else
|
26
|
+
end
|
27
|
+
else
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Piggyback do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Essential.create(:position => 1).create_detail(
|
7
|
+
:name => "nice",
|
8
|
+
:awesome => true,
|
9
|
+
:position => 23,
|
10
|
+
:birthday => "18.12.1974",
|
11
|
+
:baggage => {:key => "value"})
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should read attributes" do
|
15
|
+
e = Essential.piggy(:detail).first
|
16
|
+
e.should_not_receive(:detail)
|
17
|
+
e.name.should eql("nice")
|
18
|
+
e.awesome.should be_true
|
19
|
+
e.position.should eql(1)
|
20
|
+
e.rank.should eql(23)
|
21
|
+
e.birthday.should eql(Date.new(1974,12,18))
|
22
|
+
e.baggage.should eql({:key => "value"})
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should read attributes from the association" do
|
26
|
+
e = Essential.first
|
27
|
+
e.name.should eql("nice")
|
28
|
+
e.awesome.should be_true
|
29
|
+
e.position.should eql(1)
|
30
|
+
e.rank.should eql(23)
|
31
|
+
e.birthday.should eql(Date.new(1974,12,18))
|
32
|
+
e.baggage.should eql({:key => "value"})
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
Root = Pathname.new(File.expand_path(File.join(File.dirname(__FILE__), '..')))
|
2
|
+
|
3
|
+
$: << Root.join('lib')
|
4
|
+
|
5
|
+
require 'fileutils'
|
6
|
+
require 'active_record'
|
7
|
+
# require 'active_support/buffered_logger'
|
8
|
+
require 'piggyback'
|
9
|
+
require 'rspec'
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.before do
|
13
|
+
ActiveRecord::Base::descendants.each{ |model| model.delete_all }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:", :verbosity => "silent")
|
18
|
+
ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(Root.join('log','test.log'))
|
19
|
+
|
20
|
+
silence_stream(STDOUT) do
|
21
|
+
ActiveRecord::Schema.define(:version => 1) do
|
22
|
+
create_table :essentials do |t|
|
23
|
+
t.integer :position
|
24
|
+
t.timestamps
|
25
|
+
end
|
26
|
+
|
27
|
+
create_table :details do |t|
|
28
|
+
t.belongs_to :essential
|
29
|
+
t.string :name
|
30
|
+
t.integer :position
|
31
|
+
t.boolean :awesome
|
32
|
+
t.date :birthday
|
33
|
+
t.text :baggage
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Essential < ActiveRecord::Base
|
40
|
+
has_one :detail
|
41
|
+
# piggyback :detail, :attributes => [:name, :awesome, :birthday, :baggage], :rank => :position
|
42
|
+
# piggyback :detail, :name, :awesome, :birthday, :baggage, :rank => :position
|
43
|
+
piggyback :detail, [:name, :awesome, :birthday, :baggage], :rank => :position
|
44
|
+
end
|
45
|
+
|
46
|
+
class Detail < ActiveRecord::Base
|
47
|
+
belongs_to :essential
|
48
|
+
serialize :baggage
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: piggyback
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Andreas Korth
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-03-20 00:00:00 +01:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Piggyback associated models with ActiveRecord
|
18
|
+
email: andreas.korth@gmail.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README.rdoc
|
25
|
+
- lib/piggyback.rb
|
26
|
+
files:
|
27
|
+
- README.rdoc
|
28
|
+
- Rakefile
|
29
|
+
- lib/piggyback.rb
|
30
|
+
- spec/piggyback_spec.rb
|
31
|
+
- spec/spec_helper.rb
|
32
|
+
- Manifest
|
33
|
+
- piggyback.gemspec
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: http://github.com/juni0r/piggyback
|
36
|
+
licenses: []
|
37
|
+
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options:
|
40
|
+
- --line-numbers
|
41
|
+
- --inline-source
|
42
|
+
- --title
|
43
|
+
- Piggyback
|
44
|
+
- --main
|
45
|
+
- README.rdoc
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "1.2"
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project: piggyback
|
63
|
+
rubygems_version: 1.5.2
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Piggyback associated models with ActiveRecord
|
67
|
+
test_files: []
|
68
|
+
|