active_hash 1.0.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NmYzYzMzOTEwZTkwZDgxNGExMTAyMDAzOTk3NTAzOTU1NzI5ZjQ2Yg==
4
+ MTE0YzI0ZDYzNTQ0OTVmOTI1Zjk4MmZlZWZlNGNlNGVmZjEyMzAxMg==
5
5
  data.tar.gz: !binary |-
6
- NDVkZmJhOTQ4NGZiZWJjNGYzMmU1ZmJiMzZmZGVmZmJlNWZkMjNiYQ==
7
- !binary "U0hBNTEy":
6
+ YTQwOGViNjkwZWJlOTkzZWZiZDgxNGU0NDgwZDVkNzE4OWY2MTE5Nw==
7
+ SHA512:
8
8
  metadata.gz: !binary |-
9
- MDIzNDE2NGZhZmUzZGNlNzUxOTZlNGUzMzcyMTU3ODg5MTQ2NjhmYzg4ZGFj
10
- MDFkYzI5NzY3MTdkZmUzNThkOTFjNmU5ZDEwOGM2YWJhZTViZDkyYzk0YjRi
11
- NTAyYzA5YWUxZmU5ZDRlMjgwZDFiYWFlZDQ3NTVkYWU1MGI1NWM=
9
+ Y2U2MGUzZjdkZDg3ODYyM2Q1NDNmODgyNTY0YjM0N2U2ZTYyOGIzZmFlYWMz
10
+ MTBmNjBjMTVjZDFhMzU4M2Q5ODcxMmI4NzYxMGNlNWNiNTg2MjZhNGQ1MmZk
11
+ MmRhYTI0OWIzMzliNWFkN2E3ZjRmMDhmNmViNzg1ZTNlYjZjYjE=
12
12
  data.tar.gz: !binary |-
13
- MjE0MDlkMjg4MTU4M2Q4Njc5NzlkYTNjYmY4MWVmZWQ4ZDRhMDRiMTgwNjVl
14
- ZDQ3ZGEwOWI0MGMxMzBlYjdlMDVjNThkMmJlYWJjMTIzMjk4YTYwOTA5NjYw
15
- NGYyMDhiYmViYzM2ZDBkNGQxZTQ2Mzg5ZDk3OGI3ZTJiMTAyZTQ=
13
+ MTU4NzNmZjdiNzM1MzkyYjA4MTMxOTJjZjhkMzJhNTQ4MTMzYTQ5NGFkOWI1
14
+ YjRmYzRlZmRhMWRmYzQ1OWY0ZjY1ZWY4NGUyZDZmMjEwNGIwMzNjZjMzZTJl
15
+ NjhjMzZlNTFkOTA2MDU4YjQwZTMwN2U0ODhjNTY3NWM2ZWIwZmM=
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ 2013-10-01 (v1.2.0)
2
+ - belongs_to is back!
3
+ - added support for primary key options for belongs_to (tomtaylor)
4
+
1
5
  2013-09-09 (v1.0.2)
2
6
  - `where(nil)` returns all results, like ActiveRecord (kugaevsky)
3
7
 
@@ -1,5 +1,5 @@
1
1
  module ActiveHash
2
2
  module Gem
3
- VERSION = "1.0.2"
3
+ VERSION = "1.2.0"
4
4
  end
5
5
  end
@@ -3,20 +3,31 @@ module ActiveHash
3
3
 
4
4
  module ActiveRecordExtensions
5
5
 
6
+ def belongs_to(name, options = {})
7
+ options = {:class_name => name.to_s.camelize }.merge(options)
8
+ klass = options[:class_name].constantize
9
+ if klass < ActiveHash::Base
10
+ belongs_to_active_hash(name, options)
11
+ else
12
+ super
13
+ end
14
+ end
15
+
6
16
  def belongs_to_active_hash(association_id, options = {})
7
17
  options = {
8
18
  :class_name => association_id.to_s.camelize,
9
19
  :foreign_key => association_id.to_s.foreign_key,
20
+ :primary_key => association_id.to_s.camelize.constantize.primary_key,
10
21
  :shortcuts => []
11
22
  }.merge(options)
12
23
  options[:shortcuts] = [options[:shortcuts]] unless options[:shortcuts].kind_of?(Array)
13
24
 
14
25
  define_method(association_id) do
15
- options[:class_name].constantize.find_by_id(send(options[:foreign_key]))
26
+ options[:class_name].constantize.send("find_by_#{options[:primary_key]}", send(options[:foreign_key]))
16
27
  end
17
28
 
18
29
  define_method("#{association_id}=") do |new_value|
19
- send "#{options[:foreign_key]}=", new_value ? new_value.id : nil
30
+ send "#{options[:foreign_key]}=", new_value ? new_value.send(options[:primary_key]) : nil
20
31
  end
21
32
 
22
33
  options[:shortcuts].each do |shortcut|
@@ -60,17 +71,19 @@ module ActiveHash
60
71
  define_method(association_id) do
61
72
  options = {
62
73
  :class_name => association_id.to_s.classify,
63
- :foreign_key => self.class.to_s.foreign_key
74
+ :foreign_key => self.class.to_s.foreign_key,
75
+ :primary_key => self.class.primary_key
64
76
  }.merge(options)
65
77
 
66
78
  klass = options[:class_name].constantize
79
+ primary_key_value = send(options[:primary_key])
67
80
 
68
81
  if ActiveRecord.const_defined?(:Relation) && klass.all.class < ActiveRecord::Relation
69
- klass.where(options[:foreign_key] => id)
82
+ klass.where(options[:foreign_key] => primary_key_value)
70
83
  elsif klass.respond_to?(:scoped)
71
- klass.scoped(:conditions => {options[:foreign_key] => id})
84
+ klass.scoped(:conditions => {options[:foreign_key] => primary_key_value})
72
85
  else
73
- klass.send("find_all_by_#{options[:foreign_key]}", id)
86
+ klass.send("find_all_by_#{options[:foreign_key]}", primary_key_value)
74
87
  end
75
88
  end
76
89
  end
@@ -95,17 +108,18 @@ module ActiveHash
95
108
 
96
109
  options = {
97
110
  :class_name => association_id.to_s.classify,
98
- :foreign_key => association_id.to_s.foreign_key
111
+ :foreign_key => association_id.to_s.foreign_key,
112
+ :primary_key => "id"
99
113
  }.merge(options)
100
114
 
101
115
  field options[:foreign_key].to_sym
102
116
 
103
117
  define_method(association_id) do
104
- options[:class_name].constantize.find_by_id(send(options[:foreign_key]))
118
+ options[:class_name].constantize.send("find_by_#{options[:primary_key]}", send(options[:foreign_key]))
105
119
  end
106
120
 
107
121
  define_method("#{association_id}=") do |new_value|
108
- attributes[options[:foreign_key].to_sym] = new_value ? new_value.id : nil
122
+ attributes[options[:foreign_key].to_sym] = new_value ? new_value.send(options[:primary_key]) : nil
109
123
  end
110
124
 
111
125
  end
@@ -5,19 +5,20 @@ describe ActiveHash::Base, "associations" do
5
5
 
6
6
  before do
7
7
  class Country < ActiveRecord::Base
8
- extend ActiveHash::Associations::ActiveRecordExtensions
9
8
  establish_connection :adapter => "sqlite3", :database => ":memory:"
10
9
  connection.create_table(:countries, :force => true) do |t|
11
10
  t.string :name
12
11
  end
12
+ extend ActiveHash::Associations::ActiveRecordExtensions
13
13
  end
14
14
 
15
15
  class School < ActiveRecord::Base
16
- extend ActiveHash::Associations::ActiveRecordExtensions
17
16
  establish_connection :adapter => "sqlite3", :database => ":memory:"
18
17
  connection.create_table(:schools, :force => true) do |t|
18
+ t.integer :country_id
19
19
  t.integer :city_id
20
20
  end
21
+ extend ActiveHash::Associations::ActiveRecordExtensions
21
22
  end
22
23
 
23
24
  class City < ActiveHash::Base
@@ -35,6 +36,7 @@ describe ActiveHash::Base, "associations" do
35
36
  establish_connection :adapter => "sqlite3", :database => ":memory:"
36
37
  connection.create_table(:books, :force => true) do |t|
37
38
  t.integer :author_id
39
+ t.integer :author_code
38
40
  t.boolean :published
39
41
  end
40
42
 
@@ -57,43 +59,117 @@ describe ActiveHash::Base, "associations" do
57
59
  describe "#has_many" do
58
60
 
59
61
  context "with ActiveRecord children" do
60
- before do
61
- @included_book_1 = Book.create! :author_id => 1, :published => true
62
- @included_book_2 = Book.create! :author_id => 1, :published => false
63
- @excluded_book = Book.create! :author_id => 2, :published => true
62
+ context "with default options" do
63
+ before do
64
+ @book_1 = Book.create! :author_id => 1, :published => true
65
+ @book_2 = Book.create! :author_id => 1, :published => false
66
+ @book_3 = Book.create! :author_id => 2, :published => true
67
+ Author.has_many :books
68
+ end
69
+
70
+ it "find the correct records" do
71
+ author = Author.create :id => 1
72
+ author.books.should == [@book_1, @book_2]
73
+ end
74
+
75
+ it "return a scope so that we can apply further scopes" do
76
+ author = Author.create :id => 1
77
+ author.books.published.should == [@book_1]
78
+ end
64
79
  end
65
80
 
66
- it "find the correct records" do
67
- Author.has_many :books
68
- author = Author.create :id => 1
69
- author.books.should == [@included_book_1, @included_book_2]
81
+ context "with a primary_key option" do
82
+ before do
83
+ @book_1 = Book.create! :author_id => 1, :published => true
84
+ @book_2 = Book.create! :author_id => 2, :published => false
85
+ @book_3 = Book.create! :author_id => 2, :published => true
86
+ Author.field :book_identifier
87
+ Author.has_many :books, :primary_key => :book_identifier
88
+ end
89
+
90
+ it "should find the correct records" do
91
+ author = Author.create :id => 1, :book_identifier => 2
92
+ author.books.should == [@book_2, @book_3]
93
+ end
94
+
95
+ it "return a scope so that we can apply further scopes" do
96
+ author = Author.create :id => 1, :book_identifier => 2
97
+ author.books.published.should == [@book_3]
98
+ end
70
99
  end
71
100
 
72
- it "return a scope so that we can apply further scopes" do
73
- Author.has_many :books
74
- author = Author.create :id => 1
75
- author.books.published.should == [@included_book_1]
101
+ context "with a foreign_key option" do
102
+ before do
103
+ @book_1 = Book.create! :author_code => 1, :published => true
104
+ @book_2 = Book.create! :author_code => 1, :published => false
105
+ @book_3 = Book.create! :author_code => 2, :published => true
106
+ Author.has_many :books, :foreign_key => :author_code
107
+ end
108
+
109
+ it "should find the correct records" do
110
+ author = Author.create :id => 1
111
+ author.books.should == [@book_1, @book_2]
112
+ end
113
+
114
+ it "return a scope so that we can apply further scopes" do
115
+ author = Author.create :id => 1
116
+ author.books.published.should == [@book_1]
117
+ end
76
118
  end
77
119
  end
78
120
 
79
121
  context "with ActiveHash children" do
80
- before do
81
- Author.field :city_id
82
- @included_author_1 = Author.create :city_id => 1
83
- @included_author_2 = Author.create :city_id => 1
84
- @excluded_author = Author.create :city_id => 2
122
+ context "with default options" do
123
+ before do
124
+ Author.field :city_id
125
+ @included_author_1 = Author.create :city_id => 1
126
+ @included_author_2 = Author.create :city_id => 1
127
+ @excluded_author = Author.create :city_id => 2
128
+ end
129
+
130
+ it "find the correct records" do
131
+ City.has_many :authors
132
+ city = City.create :id => 1
133
+ city.authors.should == [@included_author_1, @included_author_2]
134
+ end
135
+
136
+ it "uses the correct class name when passed" do
137
+ City.has_many :writers, :class_name => "Author"
138
+ city = City.create :id => 1
139
+ city.writers.should == [@included_author_1, @included_author_2]
140
+ end
85
141
  end
86
142
 
87
- it "find the correct records" do
88
- City.has_many :authors
89
- city = City.create :id => 1
90
- city.authors.should == [@included_author_1, @included_author_2]
143
+ context "with a primary_key option" do
144
+ before do
145
+ Author.field :city_id
146
+ City.field :author_identifier
147
+ @author_1 = Author.create :city_id => 1
148
+ @author_2 = Author.create :city_id => 10
149
+ @author_3 = Author.create :city_id => 10
150
+ City.has_many :authors, :primary_key => :author_identifier
151
+ end
152
+
153
+ it "finds the correct records" do
154
+ city = City.create :id => 1, :author_identifier => 10
155
+ city.authors.should == [@author_2, @author_3]
156
+ end
91
157
  end
92
158
 
93
- it "uses the correct class name when passed" do
94
- City.has_many :writers, :class_name => "Author"
95
- city = City.create :id => 1
96
- city.writers.should == [@included_author_1, @included_author_2]
159
+ context "with a foreign_key option" do
160
+ before do
161
+ Author.field :city_id
162
+ Author.field :city_identifier
163
+ @author_1 = Author.create :city_id => 1, :city_identifier => 10
164
+ @author_2 = Author.create :city_id => 10, :city_identifier => 10
165
+ @author_3 = Author.create :city_id => 10, :city_identifier => 5
166
+ City.has_many :authors, :foreign_key => :city_identifier
167
+ end
168
+
169
+ it "finds the correct records" do
170
+ city = City.create :id => 10
171
+ city.authors.should == [@author_1, @author_2]
172
+ end
97
173
  end
98
174
  end
99
175
 
@@ -101,6 +177,27 @@ describe ActiveHash::Base, "associations" do
101
177
 
102
178
  describe ActiveHash::Associations::ActiveRecordExtensions do
103
179
 
180
+ describe "#belongs_to" do
181
+ it "sets up an ActiveRecord association for non-ActiveHash objects" do
182
+ School.belongs_to :country
183
+ school = School.new
184
+ country = Country.create!
185
+ school.country = country
186
+ school.country.should == country
187
+ school.country_id.should == country.id
188
+ school.save!
189
+ school.reload
190
+ school.reload.country_id.should == country.id
191
+ end
192
+
193
+ it "calls through to belongs_to_active_hash if it's an ActiveHash object" do
194
+ School.belongs_to :city
195
+ city = City.create
196
+ school = School.create :city_id => city.id
197
+ school.city.should == city
198
+ end
199
+ end
200
+
104
201
  describe "#belongs_to_active_hash" do
105
202
  context "setting by id" do
106
203
  it "finds the correct records" do
@@ -239,6 +336,20 @@ describe ActiveHash::Base, "associations" do
239
336
  author.city_id.should == @city.id
240
337
  end
241
338
  end
339
+
340
+ describe "with a different primary key" do
341
+ before do
342
+ City.field :long_identifier
343
+ Author.belongs_to :city, :primary_key => "long_identifier"
344
+ @city = City.create :id => 1, :long_identifier => "123"
345
+ end
346
+
347
+ it "works" do
348
+ author = Author.new
349
+ author.city = @city
350
+ author.city_id.should == @city.long_identifier
351
+ end
352
+ end
242
353
  end
243
354
 
244
355
  describe "#has_one" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_hash
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dean
@@ -148,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
148
  version: '0'
149
149
  requirements: []
150
150
  rubyforge_project:
151
- rubygems_version: 2.0.5
151
+ rubygems_version: 2.1.5
152
152
  signing_key:
153
153
  specification_version: 3
154
154
  summary: An ActiveRecord-like model that uses a hash or file as a datasource