ruby-trello 2.2.0 → 2.3.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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +49 -10
  3. data/lib/trello.rb +47 -35
  4. data/lib/trello/action.rb +4 -2
  5. data/lib/trello/association_builder/has_many.rb +17 -0
  6. data/lib/trello/association_builder/has_one.rb +16 -0
  7. data/lib/trello/association_fetcher/has_many.rb +26 -0
  8. data/lib/trello/association_fetcher/has_many/fetch.rb +47 -0
  9. data/lib/trello/association_fetcher/has_many/params.rb +56 -0
  10. data/lib/trello/association_fetcher/has_one.rb +25 -0
  11. data/lib/trello/association_fetcher/has_one/fetch.rb +49 -0
  12. data/lib/trello/association_fetcher/has_one/params.rb +36 -0
  13. data/lib/trello/association_infer_tool.rb +13 -0
  14. data/lib/trello/association_proxy.rb +1 -1
  15. data/lib/trello/basic_data.rb +7 -48
  16. data/lib/trello/board.rb +1 -1
  17. data/lib/trello/card.rb +88 -36
  18. data/lib/trello/custom_field.rb +26 -9
  19. data/lib/trello/custom_field_item.rb +32 -12
  20. data/lib/trello/label.rb +24 -7
  21. data/lib/trello/member.rb +1 -1
  22. data/lib/trello/register_attributes.rb +54 -0
  23. data/spec/action_spec.rb +1 -1
  24. data/spec/card_spec.rb +98 -22
  25. data/spec/cassettes/can_add_a_file_from_url_on_a_card.yml +189 -0
  26. data/spec/cassettes/can_add_a_file_on_a_card.yml +200 -0
  27. data/spec/cassettes/can_add_a_member_to_a_card.yml +190 -0
  28. data/spec/cassettes/can_add_label_on_a_card.yml +281 -0
  29. data/spec/cassettes/can_close_bong_a_card.yml +189 -0
  30. data/spec/cassettes/can_get_actions.yml +196 -0
  31. data/spec/cassettes/can_get_attachments.yml +187 -0
  32. data/spec/cassettes/can_get_comments.yml +193 -0
  33. data/spec/cassettes/can_move_a_card_to_another_board_with_specific_list.yml +373 -0
  34. data/spec/cassettes/can_move_a_card_to_another_board_without_specific_list.yml +281 -0
  35. data/spec/cassettes/can_move_a_card_to_another_list.yml +281 -0
  36. data/spec/cassettes/can_remove_a_member_from_a_card.yml +185 -0
  37. data/spec/cassettes/can_remove_an_attachment_on_a_card.yml +277 -0
  38. data/spec/cassettes/can_remove_an_upvote_on_a_card.yml +465 -0
  39. data/spec/cassettes/can_remove_label_on_a_card.yml +279 -0
  40. data/spec/cassettes/can_success_add_comment_to_a_card.yml +196 -0
  41. data/spec/cassettes/can_success_copy_checklist_to_a_card.yml +281 -0
  42. data/spec/cassettes/can_success_copy_checklist_to_a_card_without_name_pos.yml +281 -0
  43. data/spec/cassettes/can_success_create_a_card.yml +99 -0
  44. data/spec/cassettes/can_success_create_new_checklist_to_a_card.yml +189 -0
  45. data/spec/cassettes/can_success_delete_card.yml +185 -0
  46. data/spec/cassettes/can_success_upate_a_card.yml +189 -0
  47. data/spec/cassettes/can_success_update_bong_a_card.yml +191 -0
  48. data/spec/cassettes/can_upvote_on_a_card.yml +469 -0
  49. data/spec/cassettes/card_find_with_id_and_get_all_fields.yml +95 -0
  50. data/spec/cassettes/card_find_with_id_and_get_specific_fields.yml +96 -0
  51. data/spec/cassettes/custom_field_item_save_1.yml +97 -0
  52. data/spec/cassettes/custom_field_item_save_2.yml +281 -0
  53. data/spec/cassettes/get_board_of_card.yml +187 -0
  54. data/spec/cassettes/get_check_item_states_of_card.yml +188 -0
  55. data/spec/cassettes/get_checklists_of_card.yml +187 -0
  56. data/spec/cassettes/get_cover_image_of_card.yml +187 -0
  57. data/spec/cassettes/get_custom_field_items_of_card.yml +187 -0
  58. data/spec/cassettes/get_list_of_card.yml +188 -0
  59. data/spec/cassettes/get_lists.yml +187 -0
  60. data/spec/cassettes/get_members_of_card.yml +189 -0
  61. data/spec/cassettes/get_plugin_data_of_card.yml +187 -0
  62. data/spec/cassettes/get_voters_of_card.yml +188 -0
  63. data/spec/cassettes/remove_upvote_on_a_card_when_have_not_voted.yml +366 -0
  64. data/spec/cassettes/revote_on_a_card.yml +464 -0
  65. data/spec/custom_field_item_spec.rb +74 -0
  66. data/spec/custom_field_spec.rb +76 -0
  67. data/spec/integration/basic_data/many_spec.rb +123 -0
  68. data/spec/integration/basic_data/one_spec.rb +84 -0
  69. data/spec/integration/basic_data/register_attributes_spec.rb +75 -0
  70. data/spec/integration/board_lists_spec.rb +21 -0
  71. data/spec/integration/card/add_and_remove_attachment_spec.rb +45 -0
  72. data/spec/integration/card/add_and_remove_label_spec.rb +35 -0
  73. data/spec/integration/card/add_checklist_spec.rb +32 -0
  74. data/spec/integration/card/add_comment_spec.rb +19 -0
  75. data/spec/integration/card/add_memeber_spec.rb +19 -0
  76. data/spec/integration/card/associations/actions_spec.rb +17 -0
  77. data/spec/integration/card/associations/attachments_spec.rb +18 -0
  78. data/spec/integration/card/associations/board_spec.rb +17 -0
  79. data/spec/integration/card/associations/check_item_states_spec.rb +17 -0
  80. data/spec/integration/card/associations/checklists_spec.rb +18 -0
  81. data/spec/integration/card/associations/comments_spec.rb +19 -0
  82. data/spec/integration/card/associations/cover_image_spec.rb +18 -0
  83. data/spec/integration/card/associations/custom_field_items_spec.rb +18 -0
  84. data/spec/integration/card/associations/list_spec.rb +16 -0
  85. data/spec/integration/card/associations/members_spec.rb +18 -0
  86. data/spec/integration/card/associations/plugin_data_spec.rb +18 -0
  87. data/spec/integration/card/associations/voters_spec.rb +17 -0
  88. data/spec/integration/card/close!_spec.rb +16 -0
  89. data/spec/integration/card/create_new_check_list_spec.rb +19 -0
  90. data/spec/integration/card/create_spec.rb +50 -0
  91. data/spec/integration/card/delete_spec.rb +16 -0
  92. data/spec/integration/card/find_spec.rb +67 -0
  93. data/spec/integration/card/move_to_board_spec.rb +36 -0
  94. data/spec/integration/card/move_to_list_spec.rb +20 -0
  95. data/spec/integration/card/remove_member_spec.rb +19 -0
  96. data/spec/integration/card/save_spec.rb +61 -0
  97. data/spec/integration/card/update!_spec.rb +53 -0
  98. data/spec/integration/card/vote_spec.rb +50 -0
  99. data/spec/integration/custom_field_item_spec.rb +47 -0
  100. data/spec/label_spec.rb +79 -0
  101. data/spec/spec_helper.rb +48 -23
  102. data/spec/unit/trello/association_builder/has_many_spec.rb +36 -0
  103. data/spec/unit/trello/association_builder/has_one_spec.rb +36 -0
  104. data/spec/unit/trello/association_fetcher/has_many/fetch_spec.rb +38 -0
  105. data/spec/unit/trello/association_fetcher/has_many/params_spec.rb +107 -0
  106. data/spec/unit/trello/association_fetcher/has_many_spec.rb +50 -0
  107. data/spec/unit/trello/association_fetcher/has_one/fetch_spec.rb +51 -0
  108. data/spec/unit/trello/association_fetcher/has_one/params_spec.rb +81 -0
  109. data/spec/unit/trello/association_fetcher/has_one_spec.rb +49 -0
  110. data/spec/unit/trello/association_infer_tool_spec.rb +41 -0
  111. data/spec/unit/trello/basic_data_spec.rb +54 -0
  112. data/spec/unit/trello/card_spec.rb +103 -0
  113. metadata +185 -6
@@ -0,0 +1,36 @@
1
+ module Trello
2
+ module AssociationFetcher
3
+ class HasOne
4
+ class Params
5
+ attr_reader :association_owner
6
+
7
+ def initialize(association_owner:, association_name:, association_options:)
8
+ @association_owner = association_owner
9
+ @association_name = association_name
10
+ @association_options = association_options || {}
11
+ end
12
+
13
+ def association_class
14
+ association_options[:via] || infer_class_on(association_name)
15
+ end
16
+
17
+ def association_restful_name
18
+ association_options[:path]
19
+ end
20
+
21
+ def association_restful_id
22
+ id_field = association_options[:using] || :id
23
+ association_owner.send(id_field)
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :association_name, :association_options
29
+
30
+ def infer_class_on(name)
31
+ AssociationInferTool.infer_class_on_name(name)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,13 @@
1
+ module Trello
2
+ class AssociationInferTool
3
+ class << self
4
+ def infer_restful_resource_on_class(klass)
5
+ klass.to_s.split('::').last.downcase.pluralize
6
+ end
7
+
8
+ def infer_class_on_name(name)
9
+ Trello.const_get(name.to_s.singularize.camelize)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -31,7 +31,7 @@ module Trello
31
31
  end
32
32
 
33
33
  def to_ary
34
- proxy_assocation.dup
34
+ proxy_assocation.target.dup
35
35
  end
36
36
  alias_method :to_a, :to_ary
37
37
 
@@ -42,61 +42,20 @@ module Trello
42
42
  end
43
43
  end
44
44
 
45
- def self.register_attributes(*names)
46
- options = { readonly: [] }
47
- options.merge!(names.pop) if names.last.kind_of? Hash
48
-
49
- # Defines the attribute getter and setters.
50
- class_eval do
51
- define_method :attributes do
52
- @__attributes ||= names.reduce({}) { |hash, k| hash.merge(k.to_sym => nil) }
53
- end
54
-
55
- names.each do |key|
56
- define_method(:"#{key}") { @__attributes[key] }
57
-
58
- unless options[:readonly].include?(key.to_sym)
59
- define_method :"#{key}=" do |val|
60
- send(:"#{key}_will_change!") unless val == @__attributes[key]
61
- @__attributes[key] = val
62
- end
63
- end
64
- end
45
+ def self.register_attributes(*names_and_options)
46
+ has_opts = names_and_options.last.kind_of?(Hash)
47
+ readonly_attributes = has_opts ? names_and_options.pop[:readonly] : []
48
+ attributes = names_and_options
65
49
 
66
- define_attribute_methods names
67
- end
50
+ RegisterAttributes.execute(self, attributes, readonly_attributes)
68
51
  end
69
52
 
70
53
  def self.one(name, opts = {})
71
- class_eval do
72
- define_method(:"#{name}") do |*args|
73
- options = opts.dup
74
- klass = options.delete(:via) || Trello.const_get(name.to_s.camelize)
75
- ident = options.delete(:using) || :id
76
- path = options.delete(:path)
77
-
78
- if path
79
- client.find(path, self.send(ident))
80
- else
81
- klass.find(self.send(ident))
82
- end
83
- end
84
- end
54
+ AssociationBuilder::HasOne.build(self, name, opts)
85
55
  end
86
56
 
87
57
  def self.many(name, opts = {})
88
- class_eval do
89
- define_method(:"#{name}") do |*args|
90
- options = opts.dup
91
- resource = options.delete(:in) || self.class.to_s.split("::").last.downcase.pluralize
92
- klass = options.delete(:via) || Trello.const_get(name.to_s.singularize.camelize)
93
- path = options.delete(:path) || name
94
- params = options.merge(args[0] || {})
95
-
96
- resources = client.find_many(klass, "/#{resource}/#{id}/#{path}", params)
97
- MultiAssociation.new(self, resources).proxy
98
- end
99
- end
58
+ AssociationBuilder::HasMany.build(self, name, opts)
100
59
  end
101
60
 
102
61
  def self.client
data/lib/trello/board.rb CHANGED
@@ -72,7 +72,7 @@ module Trello
72
72
  fail "Cannot save new instance." unless self.id
73
73
 
74
74
  @previously_changed = changes
75
- @changed_attributes.try(:clear)
75
+ @changed_attributes.clear if @changed_attributes.respond_to?(:clear)
76
76
  changes_applied if respond_to?(:changes_applied)
77
77
 
78
78
  fields = {
data/lib/trello/card.rb CHANGED
@@ -169,36 +169,29 @@ module Trello
169
169
  #
170
170
  # @return [Trello::Card] self
171
171
  def update_fields(fields)
172
- attributes[:id] = fields[SYMBOL_TO_STRING[:id]] || attributes[:id]
173
- attributes[:short_id] = fields[SYMBOL_TO_STRING[:short_id]] || attributes[:short_id]
174
- attributes[:name] = fields[SYMBOL_TO_STRING[:name]] || fields[:name] || attributes[:name]
175
- attributes[:desc] = fields[SYMBOL_TO_STRING[:desc]] || fields[:desc] || attributes[:desc]
176
- attributes[:due] = Time.iso8601(fields[SYMBOL_TO_STRING[:due]]) rescue nil if fields.has_key?(SYMBOL_TO_STRING[:due])
177
- attributes[:due] = fields[:due] if fields.has_key?(:due)
178
- attributes[:due_complete] = fields[SYMBOL_TO_STRING[:due_complete]] if fields.has_key?(SYMBOL_TO_STRING[:due_complete])
179
- attributes[:due_complete] ||= false
180
- attributes[:closed] = fields[SYMBOL_TO_STRING[:closed]] if fields.has_key?(SYMBOL_TO_STRING[:closed])
181
- attributes[:url] = fields[SYMBOL_TO_STRING[:url]] || attributes[:url]
182
- attributes[:short_url] = fields[SYMBOL_TO_STRING[:short_url]] || attributes[:short_url]
183
- attributes[:board_id] = fields[SYMBOL_TO_STRING[:board_id]] || attributes[:board_id]
184
- attributes[:member_ids] = fields[SYMBOL_TO_STRING[:member_ids]] || fields[:member_ids] || attributes[:member_ids]
185
- attributes[:list_id] = fields[SYMBOL_TO_STRING[:list_id]] || fields[:list_id] || attributes[:list_id]
186
- attributes[:pos] = fields[SYMBOL_TO_STRING[:pos]] || fields[:pos] || attributes[:pos]
187
- attributes[:labels] = (fields[SYMBOL_TO_STRING[:labels]] || []).map { |lbl| Trello::Label.new(lbl) }.presence || attributes[:labels].presence || []
188
- attributes[:card_labels] = fields[SYMBOL_TO_STRING[:card_labels]] || fields[:card_labels] || attributes[:card_labels]
189
- attributes[:last_activity_date] = Time.iso8601(fields[SYMBOL_TO_STRING[:last_activity_date]]) rescue nil if fields.has_key?(SYMBOL_TO_STRING[:last_activity_date])
190
- attributes[:cover_image_id] = fields[SYMBOL_TO_STRING[:cover_image_id]] || attributes[:cover_image_id]
191
- attributes[:badges] = fields[SYMBOL_TO_STRING[:badges]] || attributes[:badges]
192
- attributes[:card_members] = fields[SYMBOL_TO_STRING[:card_members]] || attributes[:card_members]
193
- attributes[:source_card_id] = fields[SYMBOL_TO_STRING[:source_card_id]] || fields[:source_card_id] || attributes[:source_card_id]
194
- attributes[:source_card_properties] = fields[SYMBOL_TO_STRING[:source_card_properties]] || fields[:source_card_properties] || attributes[:source_card_properties]
195
- self
172
+ %i[
173
+ name desc due due_complete closed
174
+ board_id member_ids list_id pos
175
+ card_labels cover_image_id
176
+ ].each do |key|
177
+ send("#{key}_will_change!") if fields_has_key?(fields, key)
178
+ end
179
+
180
+ initialize_fields(fields)
181
+ end
182
+
183
+ def initialize(fields = {})
184
+ initialize_fields(fields)
196
185
  end
197
186
 
198
187
  # Returns a reference to the board this card is part of.
199
188
  one :board, path: :boards, using: :board_id
189
+
200
190
  # Returns a reference to the cover image attachment
201
- one :cover_image, path: :attachments, using: :cover_image_id
191
+ def cover_image(params = {})
192
+ response = client.get("/cards/#{id}/attachments/#{cover_image_id}", params)
193
+ CoverImage.from_response(response)
194
+ end
202
195
 
203
196
  # Returns a list of checklists associated with the card.
204
197
  #
@@ -271,16 +264,41 @@ module Trello
271
264
  #
272
265
  # @raise [Trello::Error] if the card could not be updated.
273
266
  #
274
- # @return [String] The JSON representation of the updated card returned by
275
- # the Trello API.
267
+ # @return [Trello::Card] updated self
276
268
  def update!
277
269
  @previously_changed = changes
278
270
  # extract only new values to build payload
279
271
  payload = Hash[changes.map { |key, values| [SYMBOL_TO_STRING[key.to_sym].to_sym, values[1]] }]
280
- @changed_attributes.try(:clear)
272
+
273
+ response = client.put("/cards/#{id}", payload)
274
+ updated_card = from_response(response)
275
+
276
+ @changed_attributes.clear if @changed_attributes.respond_to?(:clear)
281
277
  changes_applied if respond_to?(:changes_applied)
282
278
 
283
- client.put("/cards/#{id}", payload)
279
+ attributes[:id] = updated_card.id
280
+ attributes[:short_id] = updated_card.short_id
281
+ attributes[:name] = updated_card.name
282
+ attributes[:desc] = updated_card.desc
283
+ attributes[:due] = updated_card.due
284
+ attributes[:due_complete] = updated_card.due_complete
285
+ attributes[:closed] = updated_card.closed
286
+ attributes[:url] = updated_card.url
287
+ attributes[:short_url] = updated_card.short_url
288
+ attributes[:board_id] = updated_card.board_id
289
+ attributes[:member_ids] = updated_card.member_ids
290
+ attributes[:list_id] = updated_card.list_id
291
+ attributes[:pos] = updated_card.pos
292
+ attributes[:labels] = updated_card.labels
293
+ attributes[:card_labels] = updated_card.card_labels
294
+ attributes[:last_activity_date] = updated_card.last_activity_date
295
+ attributes[:cover_image_id] = updated_card.cover_image_id
296
+ attributes[:badges] = updated_card.badges
297
+ attributes[:card_members] = updated_card.card_members
298
+ attributes[:source_card_id] = updated_card.source_card_id
299
+ attributes[:source_card_properties] = updated_card.source_card_properties
300
+
301
+ self
284
302
  end
285
303
 
286
304
  # Delete this card
@@ -315,7 +333,7 @@ module Trello
315
333
 
316
334
  # Is the record valid?
317
335
  def valid?
318
- name && list_id
336
+ !(name && list_id).nil?
319
337
  end
320
338
 
321
339
  # Add a comment with the supplied text.
@@ -324,10 +342,12 @@ module Trello
324
342
  end
325
343
 
326
344
  # Add a checklist to this card
327
- def add_checklist(checklist)
328
- client.post("/cards/#{id}/checklists", {
329
- value: checklist.id
330
- })
345
+ def add_checklist(checklist, name: nil, position: nil)
346
+ payload = { idChecklistSource: checklist.id }
347
+ payload[:name] = name if name
348
+ payload[:pos] = position if position
349
+
350
+ client.post("/cards/#{id}/checklists", payload)
331
351
  end
332
352
 
333
353
  # create a new checklist and add it to this card
@@ -366,14 +386,14 @@ module Trello
366
386
 
367
387
  # Add a member to this card
368
388
  def add_member(member)
369
- client.post("/cards/#{id}/members", {
389
+ client.post("/cards/#{id}/idMembers", {
370
390
  value: member.id
371
391
  })
372
392
  end
373
393
 
374
394
  # Remove a member from this card
375
395
  def remove_member(member)
376
- client.delete("/cards/#{id}/members/#{member.id}")
396
+ client.delete("/cards/#{id}/idMembers/#{member.id}")
377
397
  end
378
398
 
379
399
  # Current authenticated user upvotes a card
@@ -465,5 +485,37 @@ module Trello
465
485
  def me
466
486
  @me ||= Member.find(:me)
467
487
  end
488
+
489
+ def fields_has_key?(fields, key)
490
+ fields.key?(SYMBOL_TO_STRING[key]) || fields.key?(key)
491
+ end
492
+
493
+ def initialize_fields(fields)
494
+ attributes[:id] = fields[SYMBOL_TO_STRING[:id]] || attributes[:id]
495
+ attributes[:short_id] = fields[SYMBOL_TO_STRING[:short_id]] || attributes[:short_id]
496
+ attributes[:name] = fields[SYMBOL_TO_STRING[:name]] || fields[:name] || attributes[:name]
497
+ attributes[:desc] = fields[SYMBOL_TO_STRING[:desc]] || fields[:desc] || attributes[:desc]
498
+ attributes[:due] = Time.iso8601(fields[SYMBOL_TO_STRING[:due]]) rescue nil if fields.has_key?(SYMBOL_TO_STRING[:due])
499
+ attributes[:due] = fields[:due] if fields.has_key?(:due)
500
+ attributes[:due_complete] = fields[SYMBOL_TO_STRING[:due_complete]] if fields.has_key?(SYMBOL_TO_STRING[:due_complete])
501
+ attributes[:due_complete] ||= false
502
+ attributes[:closed] = fields[SYMBOL_TO_STRING[:closed]] if fields.has_key?(SYMBOL_TO_STRING[:closed])
503
+ attributes[:url] = fields[SYMBOL_TO_STRING[:url]] || attributes[:url]
504
+ attributes[:short_url] = fields[SYMBOL_TO_STRING[:short_url]] || attributes[:short_url]
505
+ attributes[:board_id] = fields[SYMBOL_TO_STRING[:board_id]] || attributes[:board_id]
506
+ attributes[:member_ids] = fields[SYMBOL_TO_STRING[:member_ids]] || fields[:member_ids] || attributes[:member_ids]
507
+ attributes[:list_id] = fields[SYMBOL_TO_STRING[:list_id]] || fields[:list_id] || attributes[:list_id]
508
+ attributes[:pos] = fields[SYMBOL_TO_STRING[:pos]] || fields[:pos] || attributes[:pos]
509
+ attributes[:labels] = (fields[SYMBOL_TO_STRING[:labels]] || []).map { |lbl| Trello::Label.new(lbl) }.presence || attributes[:labels].presence || []
510
+ attributes[:card_labels] = fields[SYMBOL_TO_STRING[:card_labels]] || fields[:card_labels] || attributes[:card_labels]
511
+ attributes[:last_activity_date] = Time.iso8601(fields[SYMBOL_TO_STRING[:last_activity_date]]) rescue nil if fields.has_key?(SYMBOL_TO_STRING[:last_activity_date])
512
+ attributes[:cover_image_id] = fields[SYMBOL_TO_STRING[:cover_image_id]] || attributes[:cover_image_id]
513
+ attributes[:badges] = fields[SYMBOL_TO_STRING[:badges]] || attributes[:badges]
514
+ attributes[:card_members] = fields[SYMBOL_TO_STRING[:card_members]] || attributes[:card_members]
515
+ attributes[:source_card_id] = fields[SYMBOL_TO_STRING[:source_card_id]] || fields[:source_card_id] || attributes[:source_card_id]
516
+ attributes[:source_card_properties] = fields[SYMBOL_TO_STRING[:source_card_properties]] || fields[:source_card_properties] || attributes[:source_card_properties]
517
+ self
518
+ end
519
+
468
520
  end
469
521
  end
@@ -58,14 +58,14 @@ module Trello
58
58
  many :custom_field_options, path: 'options'
59
59
 
60
60
  def update_fields(fields)
61
- attributes[:id] = fields[SYMBOL_TO_STRING[:id]] || fields[:id] || attributes[:id]
62
- attributes[:name] = fields[SYMBOL_TO_STRING[:name]] || fields[:name] || attributes[:name]
63
- attributes[:model_id] = fields[SYMBOL_TO_STRING[:model_id]] || fields[:model_id] || attributes[:model_id]
64
- attributes[:model_type] = fields[SYMBOL_TO_STRING[:model_type]] || fields[:model_type] || attributes[:model_type]
65
- attributes[:field_group] = fields[SYMBOL_TO_STRING[:field_group]] || fields[:field_group] || attributes[:field_group]
66
- attributes[:type] = fields[SYMBOL_TO_STRING[:type]] || fields[:type] || attributes[:type]
67
- attributes[:pos] = fields[SYMBOL_TO_STRING[:pos]] || fields[:pos] || attributes[:pos]
68
- self
61
+ send('name_will_change!') if fields_has_key?(fields, :name)
62
+ send('pos_will_change!') if fields_has_key?(fields, :pos)
63
+
64
+ initialize_fields(fields)
65
+ end
66
+
67
+ def initialize(fields = {})
68
+ initialize_fields(fields)
69
69
  end
70
70
 
71
71
  # Saves a record.
@@ -88,7 +88,7 @@ module Trello
88
88
  @previously_changed = changes
89
89
  # extract only new values to build payload
90
90
  payload = Hash[changes.map { |key, values| [SYMBOL_TO_STRING[key.to_sym].to_sym, values[1]] }]
91
- @changed_attributes.try(:clear)
91
+ @changed_attributes.clear if @changed_attributes.respond_to?(:clear)
92
92
  changes_applied if respond_to?(:changes_applied)
93
93
 
94
94
  client.put("/customFields/#{id}", payload)
@@ -110,5 +110,22 @@ module Trello
110
110
  def delete_option(option_id)
111
111
  client.delete("/customFields/#{id}/options/#{option_id}")
112
112
  end
113
+
114
+ private
115
+
116
+ def fields_has_key?(fields, key)
117
+ fields.key?(SYMBOL_TO_STRING[key]) || fields.key?(key)
118
+ end
119
+
120
+ def initialize_fields(fields)
121
+ attributes[:id] = fields[SYMBOL_TO_STRING[:id]] || fields[:id] || attributes[:id]
122
+ attributes[:name] = fields[SYMBOL_TO_STRING[:name]] || fields[:name] || attributes[:name]
123
+ attributes[:model_id] = fields[SYMBOL_TO_STRING[:model_id]] || fields[:model_id] || attributes[:model_id]
124
+ attributes[:model_type] = fields[SYMBOL_TO_STRING[:model_type]] || fields[:model_type] || attributes[:model_type]
125
+ attributes[:field_group] = fields[SYMBOL_TO_STRING[:field_group]] || fields[:field_group] || attributes[:field_group]
126
+ attributes[:type] = fields[SYMBOL_TO_STRING[:type]] || fields[:type] || attributes[:type]
127
+ attributes[:pos] = fields[SYMBOL_TO_STRING[:pos]] || fields[:pos] || attributes[:pos]
128
+ self
129
+ end
113
130
  end
114
131
  end
@@ -17,23 +17,24 @@ module Trello
17
17
  # Supply a hash of string keyed data retrieved from the Trello API representing
18
18
  # an item state.
19
19
  def update_fields(fields)
20
- attributes[:id] = fields['id'] || fields[:id] || attributes[:id]
21
- attributes[:model_id] = fields['idModel'] || fields[:model_id] || attributes[:model_id]
22
- attributes[:custom_field_id] = fields['idCustomField'] || fields[:custom_field_id] || attributes[:custom_field_id]
23
- attributes[:model_type] = fields['modelType'] || fields[:model_type] || attributes[:model_type]
24
- # Dropdown custom field items do not have a value, they have an ID that maps to
25
- # a different endpoint to get the value
26
- attributes[:option_id] = fields['idValue'] if fields.has_key?('idValue')
27
- # value format: { "text": "hello world" }
28
- attributes[:value] = fields['value'] if fields.has_key?('value')
29
- self
20
+ if fields_has_key?(fields, 'value')
21
+ send('value_will_change!')
22
+ elsif fields_has_key?(fields, 'idValue')
23
+ send('option_id_will_change!')
24
+ end
25
+
26
+ initialize_fields(fields)
27
+ end
28
+
29
+ def initialize(fields = {})
30
+ initialize_fields(fields)
30
31
  end
31
32
 
32
33
  def update!
33
34
  @previously_changed = changes
34
35
  # extract only new values to build payload
35
36
  payload = Hash[changes.map { |key, values| [key.to_sym, values[1]] }]
36
- @changed_attributes.try(:clear)
37
+ @changed_attributes.clear if @changed_attributes.respond_to?(:clear)
37
38
  changes_applied if respond_to?(:changes_applied)
38
39
 
39
40
  client.put("/card/#{model_id}/customField/#{custom_field_id}/item", payload)
@@ -49,7 +50,7 @@ module Trello
49
50
  # If we have an id, just update our fields.
50
51
  return update! if id
51
52
 
52
- from_response client.post("/card/#{model_id}/customField/#{custom_field_id}/item", {
53
+ from_response client.put("/card/#{model_id}/customField/#{custom_field_id}/item", {
53
54
  value: value
54
55
  })
55
56
  end
@@ -74,5 +75,24 @@ module Trello
74
75
  option.value
75
76
  end
76
77
  end
78
+
79
+ private
80
+
81
+ def fields_has_key?(fields, key)
82
+ fields.key?(key.to_s) || fields.key?(key.to_sym)
83
+ end
84
+
85
+ def initialize_fields(fields)
86
+ attributes[:id] = fields['id'] || fields[:id] || attributes[:id]
87
+ attributes[:model_id] = fields['idModel'] || fields[:model_id] || attributes[:model_id]
88
+ attributes[:custom_field_id] = fields['idCustomField'] || fields[:custom_field_id] || attributes[:custom_field_id]
89
+ attributes[:model_type] = fields['modelType'] || fields[:model_type] || attributes[:model_type]
90
+ # Dropdown custom field items do not have a value, they have an ID that maps to
91
+ # a different endpoint to get the value
92
+ attributes[:option_id] = fields['idValue'] || fields[:idValue] if fields_has_key?(fields, 'idValue')
93
+ # value format: { "text": "hello world" }
94
+ attributes[:value] = fields['value'] || fields[:value] if fields_has_key?(fields, 'value')
95
+ self
96
+ end
77
97
  end
78
98
  end
data/lib/trello/label.rb CHANGED
@@ -64,12 +64,14 @@ module Trello
64
64
  # Supply a hash of stringkeyed data retrieved from the Trello API representing
65
65
  # a label.
66
66
  def update_fields(fields)
67
- attributes[:id] = fields['id'] || attributes[:id]
68
- attributes[:name] = fields['name'] || fields[:name] || attributes[:name]
69
- attributes[:color] = fields['color'] || fields[:color] || attributes[:color]
70
- attributes[:board_id] = fields['idBoard'] || fields[:board_id] || attributes[:board_id]
71
- attributes[:uses] = fields['uses'] if fields.has_key?('uses')
72
- self
67
+ send('name_will_change!') if fields_has_key?(fields, :name)
68
+ send('color_will_change!') if fields_has_key?(fields, :color)
69
+
70
+ initialize_fields(fields)
71
+ end
72
+
73
+ def initialize(fields = {})
74
+ initialize_fields(fields)
73
75
  end
74
76
 
75
77
  # Returns a reference to the board this label is currently connected.
@@ -95,7 +97,7 @@ module Trello
95
97
  @previously_changed = changes
96
98
  # extract only new values to build payload
97
99
  payload = Hash[changes.map { |key, values| [SYMBOL_TO_STRING[key.to_sym].to_sym, values[1]] }]
98
- @changed_attributes.try(:clear)
100
+ @changed_attributes.clear if @changed_attributes.respond_to?(:clear)
99
101
  changes_applied if respond_to?(:changes_applied)
100
102
 
101
103
  client.put("/labels/#{id}", payload)
@@ -105,5 +107,20 @@ module Trello
105
107
  def delete
106
108
  client.delete("/labels/#{id}")
107
109
  end
110
+
111
+ private
112
+
113
+ def fields_has_key?(fields, key)
114
+ fields.key?(SYMBOL_TO_STRING[key]) || fields.key?(key)
115
+ end
116
+
117
+ def initialize_fields(fields)
118
+ attributes[:id] = fields['id'] || attributes[:id]
119
+ attributes[:name] = fields['name'] || fields[:name] || attributes[:name]
120
+ attributes[:color] = fields['color'] || fields[:color] || attributes[:color]
121
+ attributes[:board_id] = fields['idBoard'] || fields[:board_id] || attributes[:board_id]
122
+ attributes[:uses] = fields['uses'] if fields.has_key?('uses')
123
+ self
124
+ end
108
125
  end
109
126
  end