piggyback 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+