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 ADDED
@@ -0,0 +1,6 @@
1
+ README.rdoc
2
+ Rakefile
3
+ lib/piggyback.rb
4
+ spec/piggyback_spec.rb
5
+ spec/spec_helper.rb
6
+ Manifest
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
@@ -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
+