spyke 4.0.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 89f544498e8d5c745ad7255f701ff8403d9199e9
4
- data.tar.gz: cdda57ef83c4c6b3efbd7d7bcee9bc73332b2212
3
+ metadata.gz: 577ad0ebdd60714a718b17b86a679185f8f9c636
4
+ data.tar.gz: b83cf403640604c5222fdbda68bce4628dc97b9b
5
5
  SHA512:
6
- metadata.gz: 5ea490a4c53f399e4b26b4365981b8018d9d4e87e0ed6cc56285e088991eace6d727a6ec81768b6266570a0f53fb77e1b477e336dfe8b1f0be479ad644c4652f
7
- data.tar.gz: eb126a85144b37a05de296901d40b0ec1e153e519555a6e470d1751133652f8e8c87d1993403799aee88942556c0119f5f71e942952a12882b5847ad3d648139
6
+ metadata.gz: baee2b01c8e6c987c47fad6c7ec0034c5cf438e669f9f5c2b2e65a35678d6387a909fe980dc4f7b10e7f8ca5c58ac0b6206cebb7a671132097d0aada67f252ce
7
+ data.tar.gz: b02433383758e4c430749baf650aceaa005eef0e7df9f7f2bf5df07a0049b27e4ae98e58f3043c1bf2317bba2512ad06849f52771af077c52910d2925dfbd143
@@ -3,8 +3,8 @@ module Spyke
3
3
  class BelongsTo < Association
4
4
  def initialize(*args)
5
5
  super
6
- @options.reverse_merge!(uri: "#{@name.to_s.pluralize}/:id", foreign_key: "#{klass.model_name.element}_id")
7
- @params[:id] = parent.try(foreign_key)
6
+ @options.reverse_merge!(uri: "#{@name.to_s.pluralize}/:#{primary_key}", foreign_key: "#{klass.model_name.element}_id")
7
+ @params[primary_key] = parent.try(foreign_key)
8
8
  end
9
9
  end
10
10
  end
@@ -3,7 +3,7 @@ module Spyke
3
3
  class HasMany < Association
4
4
  def initialize(*args)
5
5
  super
6
- @options.reverse_merge!(uri: "#{parent.class.model_name.element.pluralize}/:#{foreign_key}/#{@name}/(:id)")
6
+ @options.reverse_merge!(uri: "#{parent_path}/:#{foreign_key}/#{@name}/(:#{primary_key})")
7
7
  @params[foreign_key] = parent.id
8
8
  end
9
9
 
@@ -22,6 +22,10 @@ module Spyke
22
22
 
23
23
  private
24
24
 
25
+ def parent_path
26
+ parent.class.model_name.element.pluralize
27
+ end
28
+
25
29
  def combine_with_existing(incoming)
26
30
  return incoming unless primary_keys_present_in_existing?
27
31
  combined = embedded_attributes + incoming
@@ -35,11 +39,11 @@ module Spyke
35
39
  end
36
40
 
37
41
  def group_by_primary_key(array)
38
- array.group_by { |h| h.with_indifferent_access[:id].to_s }
42
+ array.group_by { |h| h.with_indifferent_access[primary_key].to_s }
39
43
  end
40
44
 
41
45
  def primary_keys_present_in_existing?
42
- embedded_attributes && embedded_attributes.any? { |attr| attr.has_key?('id') }
46
+ embedded_attributes && embedded_attributes.any? { |attr| attr.has_key?(primary_key) }
43
47
  end
44
48
 
45
49
  def clear_existing!
@@ -42,11 +42,11 @@ module Spyke
42
42
  end
43
43
 
44
44
  def id
45
- attributes[:id]
45
+ attributes[primary_key]
46
46
  end
47
47
 
48
48
  def id=(value)
49
- attributes[:id] = value if value.present?
49
+ attributes[primary_key] = value if value.present?
50
50
  end
51
51
 
52
52
  def hash
@@ -69,11 +69,18 @@ module Spyke
69
69
  private
70
70
 
71
71
  def use_setters(attributes)
72
+ # Set id attribute directly if using a custom primary key alongside an attribute named "id" to avoid clobbering
73
+ set_attribute :id, attributes.delete(:id) if conflicting_ids?(attributes)
74
+
72
75
  attributes.each do |key, value|
73
76
  send "#{key}=", value
74
77
  end
75
78
  end
76
79
 
80
+ def conflicting_ids?(attributes)
81
+ primary_key != :id && attributes.key?(:id) && attributes.key?(primary_key)
82
+ end
83
+
77
84
  def method_missing(name, *args, &block)
78
85
  case
79
86
  when association?(name) then association(name).load
@@ -125,7 +132,7 @@ module Spyke
125
132
  end
126
133
 
127
134
  def inspect_attributes
128
- attributes.except(:id).map { |k, v| "#{k}: #{v.inspect}" }.join(' ')
135
+ attributes.except(primary_key).map { |k, v| "#{k}: #{v.inspect}" }.join(' ')
129
136
  end
130
137
  end
131
138
  end
@@ -72,7 +72,7 @@ module Spyke
72
72
  end
73
73
 
74
74
  def default_uri
75
- "#{model_name.element.pluralize}/(:id)"
75
+ "#{model_name.element.pluralize}/(:#{primary_key})"
76
76
  end
77
77
  end
78
78
 
@@ -10,6 +10,9 @@ module Spyke
10
10
 
11
11
  class_attribute :callback_methods, instance_accessor: false
12
12
  self.callback_methods = { create: :post, update: :put }.freeze
13
+
14
+ class_attribute :primary_key
15
+ self.primary_key = :id
13
16
  end
14
17
 
15
18
  module ClassMethods
@@ -24,7 +27,7 @@ module Spyke
24
27
 
25
28
  def find(id)
26
29
  raise ResourceNotFound if id.blank?
27
- where(id: id).find_one || raise(ResourceNotFound)
30
+ where(primary_key => id).find_one || raise(ResourceNotFound)
28
31
  end
29
32
 
30
33
  def fetch
@@ -38,7 +41,7 @@ module Spyke
38
41
  end
39
42
 
40
43
  def destroy(id = nil)
41
- new(id: id).destroy
44
+ new(primary_key => id).destroy
42
45
  end
43
46
  end
44
47
 
@@ -1,3 +1,3 @@
1
1
  module Spyke
2
- VERSION = '4.0.1'
2
+ VERSION = '4.1.0'
3
3
  end
@@ -307,14 +307,14 @@ module Spyke
307
307
  assert_equal %w{ flavor }, recipe.groups.map(&:title)
308
308
  end
309
309
 
310
- def test_nested_attributes_merging_with_existing_when_ids_present?
310
+ def test_nested_attributes_merging_with_existing_when_ids_present
311
311
  recipe = Recipe.new(groups_attributes: [{ id: 1, title: 'starter', description: 'nice' }, { id: 2, title: 'sauce', description: 'spicy' }])
312
312
  recipe.attributes = { groups_attributes: [{ 'id' => '2', 'title' => 'flavor' }, { 'title' => 'spices', 'description' => 'lovely' }, { 'title' => 'sweetener', 'description' => 'sweet' }] }
313
313
  assert_equal %w{ starter flavor spices sweetener }, recipe.groups.map(&:title)
314
314
  assert_equal %w{ nice spicy lovely sweet }, recipe.groups.map(&:description)
315
315
  end
316
316
 
317
- def test_nested_attributes_appending_to_existing_when_ids_present?
317
+ def test_nested_attributes_appending_to_existing_when_ids_present
318
318
  recipe = Recipe.new(groups_attributes: [{ id: 1, title: 'starter' }, { id: 2, title: 'sauce' }])
319
319
  recipe.attributes = { groups_attributes: [{ title: 'flavor' }] }
320
320
  assert_equal %w{ starter sauce flavor }, recipe.groups.map(&:title)
@@ -428,5 +428,27 @@ module Spyke
428
428
  Cookbook::Tip.new.votes
429
429
  end
430
430
  end
431
+
432
+ def test_custom_primary_key_for_belongs_to
433
+ comment_endpoint = stub_request(:get, 'http://sushi.com/comments/1').to_return_json(result: { user_id: 1 })
434
+ user_endpoint = stub_request(:get, 'http://sushi.com/users/1').to_return_json(result: { id: 2 })
435
+ user = Comment.find(1).user
436
+ assert_equal 2, user.id
437
+ assert_requested comment_endpoint
438
+ assert_requested user_endpoint
439
+ end
440
+
441
+ def test_custom_primary_key_for_has_many
442
+ stub_request(:get, 'http://sushi.com/comments/1').to_return_json(result: { users: [{ id: 1 }] })
443
+ comment = Comment.find(1)
444
+ assert_equal 1, comment.users.first.id
445
+ end
446
+
447
+ def test_custom_primary_key_with_nested_attributes
448
+ comment = Comment.new(users_attributes: [{ uuid: 1, name: "user_1" }])
449
+ comment.attributes = { users_attributes: [{ uuid: 1, name: "user_1_new_name"}] }
450
+ assert_equal %w{ user_1_new_name }, comment.users.map(&:name)
451
+ assert_equal [1], comment.users.map(&:id)
452
+ end
431
453
  end
432
454
  end
@@ -139,7 +139,7 @@ module Spyke
139
139
  recipe = Recipe.new
140
140
  assert_equal '#<Recipe(recipes/(:id)) id: nil >', recipe.inspect
141
141
  user = Recipe.new.build_user
142
- assert_equal '#<User(users/:id) id: nil >', user.inspect
142
+ assert_equal '#<User(users/:uuid) id: nil >', user.inspect
143
143
  group = Recipe.new.groups.build
144
144
  assert_equal '#<Group(recipes/:recipe_id/groups/(:id)) id: nil recipe_id: nil>', group.inspect
145
145
  end
@@ -168,5 +168,33 @@ module Spyke
168
168
 
169
169
  Spyke::Base.connection.url_prefix = previous
170
170
  end
171
+
172
+ def test_custom_primary_key_on_collection
173
+ endpoint = stub_request(:get, 'http://sushi.com/users').to_return_json(result: [{ uuid: 1 }])
174
+ user = User.all.first
175
+ assert_requested endpoint
176
+ assert_equal 1, user.id
177
+ assert_equal 1, user.uuid
178
+ end
179
+
180
+ def test_custom_primary_key_and_id_are_the_same
181
+ endpoint = stub_request(:get, 'http://sushi.com/users').to_return_json(result: [{ uuid: 1 }])
182
+ user = User.all.first
183
+ assert_requested endpoint
184
+ assert_equal 1, user.id
185
+ assert_equal 1, user.uuid
186
+ assert_equal({ "uuid" => 1 }, user.attributes)
187
+ end
188
+
189
+ def test_custom_primary_key_with_response_that_also_has_id_attribute
190
+ endpoint = stub_request(:get, 'http://sushi.com/users').to_return_json(result: [{ uuid: 1, id: 42 }])
191
+ user = User.all.to_a.first
192
+ assert_requested endpoint
193
+
194
+ assert_equal 1, user.id
195
+ assert_equal 1, user.uuid
196
+ assert_equal 1, user[:uuid]
197
+ assert_equal 42, user[:id]
198
+ end
171
199
  end
172
200
  end
@@ -94,6 +94,7 @@ class Ingredient < Spyke::Base
94
94
  end
95
95
 
96
96
  class User < Spyke::Base
97
+ self.primary_key = :uuid
97
98
  has_many :recipes
98
99
  end
99
100
 
@@ -102,7 +103,10 @@ class Photo < Spyke::Base
102
103
  end
103
104
 
104
105
  class Comment < Spyke::Base
106
+ belongs_to :user
107
+ has_many :users
105
108
  scope :approved, -> { where(comment_approved: true) }
109
+ accepts_nested_attributes_for :users
106
110
  end
107
111
 
108
112
  class OtherApi < Spyke::Base
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spyke
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Balvig
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-30 00:00:00.000000000 Z
11
+ date: 2016-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -334,3 +334,4 @@ test_files:
334
334
  - test/support/fixtures.rb
335
335
  - test/support/webmock.rb
336
336
  - test/test_helper.rb
337
+ has_rdoc: