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 +9 -9
- data/CHANGELOG +4 -0
- data/lib/active_hash/version.rb +1 -1
- data/lib/associations/associations.rb +23 -9
- data/spec/associations/associations_spec.rb +138 -27
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MTE0YzI0ZDYzNTQ0OTVmOTI1Zjk4MmZlZWZlNGNlNGVmZjEyMzAxMg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
7
|
-
|
6
|
+
YTQwOGViNjkwZWJlOTkzZWZiZDgxNGU0NDgwZDVkNzE4OWY2MTE5Nw==
|
7
|
+
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Y2U2MGUzZjdkZDg3ODYyM2Q1NDNmODgyNTY0YjM0N2U2ZTYyOGIzZmFlYWMz
|
10
|
+
MTBmNjBjMTVjZDFhMzU4M2Q5ODcxMmI4NzYxMGNlNWNiNTg2MjZhNGQ1MmZk
|
11
|
+
MmRhYTI0OWIzMzliNWFkN2E3ZjRmMDhmNmViNzg1ZTNlYjZjYjE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MTU4NzNmZjdiNzM1MzkyYjA4MTMxOTJjZjhkMzJhNTQ4MTMzYTQ5NGFkOWI1
|
14
|
+
YjRmYzRlZmRhMWRmYzQ1OWY0ZjY1ZWY4NGUyZDZmMjEwNGIwMzNjZjMzZTJl
|
15
|
+
NjhjMzZlNTFkOTA2MDU4YjQwZTMwN2U0ODhjNTY3NWM2ZWIwZmM=
|
data/CHANGELOG
CHANGED
data/lib/active_hash/version.rb
CHANGED
@@ -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.
|
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.
|
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] =>
|
82
|
+
klass.where(options[:foreign_key] => primary_key_value)
|
70
83
|
elsif klass.respond_to?(:scoped)
|
71
|
-
klass.scoped(:conditions => {options[:foreign_key] =>
|
84
|
+
klass.scoped(:conditions => {options[:foreign_key] => primary_key_value})
|
72
85
|
else
|
73
|
-
klass.send("find_all_by_#{options[:foreign_key]}",
|
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.
|
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.
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
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
|
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.
|
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
|