piggyback 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/CHANGELOG +4 -0
  2. data/README.markdown +25 -25
  3. data/Rakefile +1 -1
  4. data/piggyback.gemspec +1 -1
  5. metadata +1 -1
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ = 0.2.3 / 2011-03-21
2
+
3
+ * Updated documentation.
4
+
1
5
  = 0.2.2 / 2011-03-21
2
6
 
3
7
  * Removed `piggyback_sql` method in favor of `piggyback_attributes`.
data/README.markdown CHANGED
@@ -9,7 +9,7 @@ Piggybacking refers to the technique of dynamically including attributes from an
9
9
  This is best illustrated in an example. Consider these models:
10
10
 
11
11
  class Author < ActiveRecord::Base
12
- has_many :articles
12
+ has_many :posts
13
13
  end
14
14
 
15
15
  class Post < ActiveRecord::Base
@@ -18,43 +18,43 @@ This is best illustrated in an example. Consider these models:
18
18
 
19
19
  ActiveRecord supports piggybacking simply by joining the associated table and selecting columns from it:
20
20
 
21
- >> post = Post.joins(:author).select('posts.*, author.name AS author_name').first
21
+ post = Post.joins(:author).select('posts.*, author.name AS author_name').first
22
22
 
23
- >> post.title
24
- => "Why piggybacking in ActiveRecord is flawed"
23
+ post.title
24
+ # => "Why piggybacking in ActiveRecord is flawed"
25
25
 
26
- >> post.author_name
27
- => "Alec Smart"
26
+ post.author_name
27
+ # => "Alec Smart"
28
28
 
29
- As you can see, the `name` attribute from `Author` is treated as if it were an attribute of `User`. ActiveRecord dynamically determines a model's attributes from the result set returned by the database. Every column in the result set becomes an attribute of the instantiated ActiveRecord objects. Whether the columns originate from the model's own or from a foreign table doesn't make a difference.
29
+ As you can see, the `name` attribute from `Author` is treated as if it were an attribute of `Post`. ActiveRecord dynamically determines a model's attributes from the result set returned by the database. Every column in the result set becomes an attribute of the instantiated ActiveRecord objects. Whether the columns originate from the model's own or from a foreign table doesn't make a difference.
30
30
 
31
31
  Or so it seems. Actually there is a drawback which becomes obvious when we select non-string columns:
32
32
 
33
- >> post = Post.joins(:author).select('posts.*, author.birthday AS author_birthday, author.rating AS author_rating').first
33
+ post = Post.joins(:author).select('posts.*, author.birthday AS author_birthday, author.rating AS author_rating').first
34
34
 
35
- >> post.author_birthday
36
- => "2011-03-01"
35
+ post.author_birthday
36
+ # => "2011-03-01"
37
37
 
38
- >> post.author_rating
39
- => "4.5"
38
+ post.author_rating
39
+ # => "4.5"
40
40
 
41
- Any attributes originating from foreign tables are not automatically type-casted as we would expect. This is because the database always returns results in text format. The model only knows about the data types of the columns in its own table. Since this information is used when ActiveRecord does its type-casting magic, it doesn't work with foreign columns.
41
+ Any attributes originating from the `authors` table are treated as strings instead of being automatically type-casted as we would expect. The database returns result sets as plain text and ActiveRecord needs to obtain type information separately from the table schema in order to do its type-casting magic. Unfortunately, a model only knows about the columns types in its own table, so type-casting doesn't work with columns selected from foreign tables.
42
42
 
43
- We could work around this by defining attribute reader methods in the `Post` model that implicitly converts the values:
43
+ We could work around this by defining attribute reader methods in the `Post` model that implicitly convert the values:
44
44
 
45
45
  class Post < ActiveRecord::Base
46
- ...
46
+ belongs_to :author
47
47
 
48
48
  def author_birthday
49
- Date.parse(read_attribute('author_birthday'))
49
+ Date.parse(read_attribute(:author_birthday))
50
50
  end
51
51
 
52
52
  def author_rating
53
- read_attribute('author_rating').to_f
53
+ read_attribute(:author_rating).to_f
54
54
  end
55
55
  end
56
56
 
57
- However this is tedious, error-prone and repetitive if you do it in many models. The type-casting code shown above isn't solid and would be more complex in a real-life situation in order to deal with `nil` values, for example.
57
+ However this is tedious, error-prone and repetitive if you do it in many models. The type-casting code shown above isn't solid and would quickly become more complex in a real-life application. In its current state it won't handle `nil` values properly, for example.
58
58
 
59
59
 
60
60
  ### Piggyback to the rescue!
@@ -71,13 +71,13 @@ You simply declare which association you want to piggyback and how the attribute
71
71
 
72
72
  Now you can do the following:
73
73
 
74
- >> post = Post.piggyback(:author).first
74
+ post = Post.piggyback(:author).first
75
75
 
76
- >> post.author_birthday
77
- => Tue, 01 Mar 2011
76
+ post.author_birthday
77
+ # => Tue, 01 Mar 2011
78
78
 
79
- >> post.author_rating
80
- => 4.5
79
+ post.author_rating
80
+ # => 4.5
81
81
 
82
82
  The type-casting works with any type of attribute, even with serialized ones.
83
83
 
@@ -104,7 +104,7 @@ If you want to use an SQL-expression for selecting an attribute, Piggyback can a
104
104
  piggybacks :author, :author_name => "authors.first_name || ' ' || authors.last_name"
105
105
  end
106
106
 
107
- >> post.author_name
108
- => "Donald Duck"
107
+ post.author_name
108
+ # => "Donald Duck"
109
109
 
110
110
  In fact, every value you pass in as a string will be treated as raw SQL in the SELECT clause.
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rake'
2
2
  require 'echoe'
3
3
 
4
- Echoe.new('piggyback', '0.2.2') do |p|
4
+ Echoe.new('piggyback', '0.2.3') do |p|
5
5
  p.description = "Piggyback attributes from associated models with ActiveRecord"
6
6
  p.url = "http://github.com/juni0r/piggyback"
7
7
  p.author = "Andreas Korth"
data/piggyback.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{piggyback}
5
- s.version = "0.2.2"
5
+ s.version = "0.2.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Andreas Korth"]
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: piggyback
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.2
5
+ version: 0.2.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Andreas Korth