Skip to content

Commit e7caa7a

Browse files
jeremyjungshishirmk
authored andcommitted
Allow has_one nil association (#48)
* Allow has_one nil association * add test for when has_one returns nil * modify has_one extension method, add active record test * Use try operator to support old rubies
1 parent 5f7bc4f commit e7caa7a

File tree

4 files changed

+50
-2
lines changed

4 files changed

+50
-2
lines changed

lib/extensions/has_one.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def self.define_accessors(mixin, reflection)
99
name = reflection.name
1010
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
1111
def #{name.to_s}_id
12-
association(:#{name}).reader.id
12+
association(:#{name}).reader.try(:id)
1313
end
1414
CODE
1515
end

spec/lib/extensions/active_record_spec.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
# Insert records
3030
@account_id = 2
3131
@supplier_id = 1
32+
@supplier_id_without_account = 3
3233
db.execute_batch <<-SQL
33-
insert into suppliers values ('Supplier1', #{@supplier_id});
34+
insert into suppliers values ('Supplier1', #{@supplier_id}),
35+
('SupplierWithoutAccount', #{@supplier_id_without_account});
3436
insert into accounts values ('Dollar Account', #{@account_id}, #{@supplier_id});
3537
SQL
3638
end
@@ -58,6 +60,10 @@ class Account < ActiveRecord::Base
5860
expect(Supplier.first.account_id).to eq @account_id
5961
end
6062

63+
it 'has account_id method return nil if account not present' do
64+
expect(Supplier.find(@supplier_id_without_account).account_id).to eq nil
65+
end
66+
6167
end
6268

6369
# Clean up DB

spec/lib/object_serializer_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@
6969
expect(serializable_hash['data']['relationships']['owner']['data']).to be nil
7070
end
7171

72+
it 'returns correct json when has_one returns nil' do
73+
supplier.account_id = nil
74+
json = SupplierSerializer.new(supplier).serialized_json
75+
serializable_hash = JSON.parse(json)
76+
expect(serializable_hash['data']['relationships']['account']['data']).to be nil
77+
end
78+
7279
it 'returns correct json when serializing []' do
7380
json = MovieSerializer.new([]).serialized_json
7481
serializable_hash = JSON.parse(json)

spec/shared/contexts/movie_context.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,22 @@ class MovieType
3636
attr_accessor :id, :name
3737
end
3838

39+
class Supplier
40+
attr_accessor :id, :account_id
41+
42+
def account
43+
if account_id
44+
a = Account.new
45+
a.id = account_id
46+
a
47+
end
48+
end
49+
end
50+
51+
class Account
52+
attr_accessor :id
53+
end
54+
3955
# serializers
4056
class MovieSerializer
4157
include FastJsonapi::ObjectSerializer
@@ -79,6 +95,18 @@ class MovieTypeSerializer
7995
set_type :movie_type
8096
attributes :name
8197
end
98+
99+
class SupplierSerializer
100+
include FastJsonapi::ObjectSerializer
101+
set_type :supplier
102+
has_one :account
103+
end
104+
105+
class AccountSerializer
106+
include FastJsonapi::ObjectSerializer
107+
set_type :account
108+
belongs_to :supplier
109+
end
82110
end
83111

84112

@@ -151,6 +179,13 @@ class MovieSerializer
151179
m
152180
end
153181

182+
let(:supplier) do
183+
s = Supplier.new
184+
s.id = 1
185+
s.account_id = 1
186+
s
187+
end
188+
154189
def build_movies(count)
155190
count.times.map do |i|
156191
m = Movie.new

0 commit comments

Comments
 (0)