Skip to content

Commit 91d0a1a

Browse files
committed
Merge pull request #339 from localytics/uuid_primary_key
update to support non-standard primary key has many relationships
2 parents 8638963 + 31fe5a6 commit 91d0a1a

4 files changed

Lines changed: 98 additions & 3 deletions

File tree

lib/jsonapi/resource.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ def _primary_key
596596
end
597597

598598
def _as_parent_key
599-
@_as_parent_key ||= "#{_type.to_s.singularize}_#{_primary_key}"
599+
@_as_parent_key ||= "#{_type.to_s.singularize}_id"
600600
end
601601

602602
def _allowed_filters
@@ -744,7 +744,7 @@ def _add_relationship(klass, *attrs)
744744

745745
sort_criteria = options.fetch(:sort_criteria, {})
746746
unless sort_criteria.nil? || sort_criteria.empty?
747-
order_options = self.class.construct_order_options(sort_criteria)
747+
order_options = relationship.resource_klass.construct_order_options(sort_criteria)
748748
records = resource_klass.apply_sort(records, order_options)
749749
end
750750

test/controllers/controller_test.rb

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,3 +2634,64 @@ def test_save_model_callbacks_fail
26342634
assert_match /Save failed or was cancelled/, json_response['errors'][0]['detail']
26352635
end
26362636
end
2637+
2638+
class Api::V1::MoonsControllerTest < ActionController::TestCase
2639+
def test_get_related_resource
2640+
get :get_related_resource, {crater_id: 'S56D', relationship: 'moon', source: "api/v1/craters"}
2641+
assert_response :success
2642+
assert_hash_equals json_response,
2643+
{
2644+
data: {
2645+
id: "1",
2646+
type: "moons",
2647+
links: {self: "http://test.host/moons/1"},
2648+
attributes: {name: "Titan", description: "Best known of the Saturn moons."},
2649+
relationships: {
2650+
planet: {links: {self: "http://test.host/moons/1/relationships/planet", related: "http://test.host/moons/1/planet"}},
2651+
craters: {links: {self: "http://test.host/moons/1/relationships/craters", related: "http://test.host/moons/1/craters"}}}
2652+
}
2653+
}
2654+
2655+
end
2656+
end
2657+
2658+
class Api::V1::CratersControllerTest < ActionController::TestCase
2659+
def test_show_single
2660+
get :show, {id: 'S56D'}
2661+
assert_response :success
2662+
assert json_response['data'].is_a?(Hash)
2663+
assert_equal 'S56D', json_response['data']['attributes']['code']
2664+
assert_equal 'Very large crater', json_response['data']['attributes']['description']
2665+
assert_nil json_response['included']
2666+
end
2667+
2668+
def test_get_related_resources
2669+
get :get_related_resources, {moon_id: '1', relationship: 'craters', source: "api/v1/moons"}
2670+
assert_response :success
2671+
assert_hash_equals json_response,
2672+
{
2673+
data: [
2674+
{id:"A4D3",
2675+
type:"craters",
2676+
links:{self: "http://test.host/craters/A4D3"},
2677+
attributes:{code: "A4D3", description: "Small crater"},
2678+
relationships:{moon: {links: {self: "http://test.host/craters/A4D3/relationships/moon", related: "http://test.host/craters/A4D3/moon"}}}
2679+
},
2680+
{id: "S56D",
2681+
type: "craters",
2682+
links:{self: "http://test.host/craters/S56D"},
2683+
attributes:{code: "S56D", description: "Very large crater"},
2684+
relationships:{moon: {links: {self: "http://test.host/craters/S56D/relationships/moon", related: "http://test.host/craters/S56D/moon"}}}
2685+
}
2686+
]
2687+
}
2688+
end
2689+
2690+
def test_show_relationship
2691+
get :show_relationship, {crater_id: 'S56D', relationship: 'moon'}
2692+
2693+
assert_response :success
2694+
assert_equal "moons", json_response['data']['type']
2695+
assert_equal "1", json_response['data']['id']
2696+
end
2697+
end

test/fixtures/active_record.rb

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@
9292
t.integer :planet_id
9393
end
9494

95+
create_table :craters, id: false, force: true do |t|
96+
t.string :code
97+
t.string :description
98+
t.integer :moon_id
99+
end
100+
95101
create_table :preferences, force: true do |t|
96102
t.integer :person_id
97103
t.boolean :advanced_mode, default: false
@@ -281,6 +287,14 @@ class PlanetType < ActiveRecord::Base
281287

282288
class Moon < ActiveRecord::Base
283289
belongs_to :planet
290+
291+
has_many :craters
292+
end
293+
294+
class Crater < ActiveRecord::Base
295+
self.primary_key = :code
296+
297+
belongs_to :moon
284298
end
285299

286300
class Preferences < ActiveRecord::Base
@@ -360,7 +374,7 @@ def remove(id)
360374
end
361375
end
362376

363-
class CustomerOrder < ActiveRecord::Base
377+
class Customer < ActiveRecord::Base
364378
has_many :purchase_orders
365379
end
366380

@@ -524,6 +538,9 @@ class PlanetTypesController < JSONAPI::ResourceController
524538
class MoonsController < JSONAPI::ResourceController
525539
end
526540

541+
class CratersController < JSONAPI::ResourceController
542+
end
543+
527544
class LikesController < JSONAPI::ResourceController
528545
end
529546
end
@@ -861,6 +878,18 @@ class MoonResource < JSONAPI::Resource
861878
attribute :description
862879

863880
has_one :planet
881+
has_many :craters
882+
end
883+
884+
class CraterResource < JSONAPI::Resource
885+
attribute :code
886+
attribute :description
887+
888+
has_one :moon
889+
890+
def self.verify_key(key, context = nil)
891+
key && String(key)
892+
end
864893
end
865894

866895
class PreferencesResource < JSONAPI::Resource
@@ -952,6 +981,7 @@ def subject
952981
PlanetResource = PlanetResource.dup
953982
PlanetTypeResource = PlanetTypeResource.dup
954983
MoonResource = MoonResource.dup
984+
CraterResource = CraterResource.dup
955985
PreferencesResource = PreferencesResource.dup
956986
EmployeeResource = EmployeeResource.dup
957987
FriendResource = FriendResource.dup
@@ -1226,6 +1256,8 @@ class BadlyNamedAttributesResource < JSONAPI::Resource
12261256
description: 'Saturn is the sixth planet from the Sun and the second largest planet in the Solar System, after Jupiter.',
12271257
planet_type_id: planetoid.id)
12281258
titan = Moon.create(name:'Titan', description: 'Best known of the Saturn moons.', planet_id: saturn.id)
1259+
crater1 = Crater.create(code:'S56D', description: 'Very large crater', moon_id: titan.id)
1260+
crater2 = Crater.create(code:'A4D3', description: 'Small crater', moon_id: titan.id)
12291261
makemake = Planet.create(name: 'Makemake', description: 'A small planetoid in the Kuiperbelt.', planet_type_id: planetoid.id)
12301262
uranus = Planet.create(name: 'Uranus', description: 'Insert adolescent jokes here.', planet_type_id: gas_giant.id)
12311263
jupiter = Planet.create(name: 'Jupiter', description: 'A gas giant.', planet_type_id: gas_giant.id)

test/test_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ def show_queries
110110
jsonapi_resources :planets
111111
jsonapi_resources :planet_types
112112
jsonapi_resources :moons
113+
jsonapi_resources :craters
113114
jsonapi_resources :preferences
114115
jsonapi_resources :facts
115116
jsonapi_resources :categories
@@ -130,6 +131,7 @@ def show_queries
130131
jsonapi_resources :planets
131132
jsonapi_resources :planet_types
132133
jsonapi_resources :moons
134+
jsonapi_resources :craters
133135
jsonapi_resources :preferences
134136
jsonapi_resources :likes
135137
end

0 commit comments

Comments
 (0)