Skip to content

Commit 2c6cb18

Browse files
authored
Merge pull request #607 from zendesk/jury.razumau/custom_fields
add way to refer to custom fields by their names
2 parents 950ec21 + d47f6e6 commit 2c6cb18

File tree

5 files changed

+84
-0
lines changed

5 files changed

+84
-0
lines changed

lib/zendesk_api/client.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class Client
3232
attr_reader :config
3333
# @return [Array] Custom response callbacks
3434
attr_reader :callbacks
35+
# @return [Hash] Memoized account data
36+
attr_reader :account_data
3537

3638
# Handles resources such as 'tickets'. Any options are passed to the underlying collection, except reload which disregards
3739
# memoization and creates a new Collection instance.
@@ -95,6 +97,7 @@ def initialize
9597

9698
@callbacks = []
9799
@resource_cache = {}
100+
@account_data = {}
98101

99102
check_url
100103
check_instrumentation
@@ -153,6 +156,11 @@ def self.check_deprecated_namespace_usage(attributes, name)
153156
end
154157
end
155158

159+
def refresh_custom_fields_metadata
160+
account_data[:custom_fields] ||= {}
161+
ticket_fields.each { |field| account_data[:custom_fields][field.title] = field.id }
162+
end
163+
156164
protected
157165

158166
# Called by {#connection} to build a connection. Can be overwritten in a

lib/zendesk_api/resource.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ def initialize(client, attributes = {})
7676
@attributes.clear_changes unless new_record?
7777
end
7878

79+
def account_data
80+
@client.account_data
81+
end
82+
83+
def refresh_custom_fields_metadata
84+
@client.refresh_custom_fields_metadata
85+
end
86+
7987
# Passes the method onto the attributes hash.
8088
# If the attributes are nested (e.g. { :tickets => { :id => 1 } }), passes the method onto the nested hash.
8189
def method_missing(*args, &)

lib/zendesk_api/resources.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,43 @@ def to_param
546546

547547
has_many :incidents, class: Ticket
548548

549+
class CustomFieldAccessor
550+
def initialize(ticket)
551+
@ticket = ticket
552+
end
553+
554+
def [](field_name)
555+
find_by_name(field_name)["value"]
556+
end
557+
558+
def []=(field_name, value)
559+
find_by_name(field_name)["value"] = value
560+
end
561+
562+
private
563+
564+
def find_by_name(field_name)
565+
@ticket.refresh_custom_fields_metadata unless @ticket.account_data.has_key?(:custom_fields)
566+
567+
custom_field_id = @ticket.account_data[:custom_fields][field_name]
568+
raise ArgumentError, "No custom field named '#{field_name}' found in field definitions" if custom_field_id.nil?
569+
570+
custom_field = @ticket.custom_fields.find { |cf| cf["id"] == custom_field_id }
571+
raise ArgumentError, "No custom field with id #{custom_field_id} found. Field name: '#{field_name}'" if custom_field.nil?
572+
573+
custom_field
574+
end
575+
end
576+
577+
# Returns a custom field accessor that supports bracket notation.
578+
# Usage:
579+
# ticket.custom_field["field name"] # get
580+
# ticket.custom_field["field name"] = "value" # set
581+
# You need to call `save!` on a ticket after changing a custom field value.
582+
def custom_field
583+
@custom_field_accessor ||= CustomFieldAccessor.new(self)
584+
end
585+
549586
# Gets a incremental export of tickets from the start_time until now.
550587
# @param [Client] client The {Client} object to be used
551588
# @param [Integer] start_time The start_time parameter

spec/live/Readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ In case you want to create a test account from scratch:
1212
- Add photo to user profile of that end user.
1313
- Create a new ticket and cc "zendesk-api-client-ruby-end-user-#{client.config.username}" (run tests once to create this user)
1414
- Ensure you allow admins to set up user password (or `POST /api/v2/users/{user_id}/password.json` will fail). You can check this in the admin centre > security > advanced
15+
- Add ticket custom field with the display name "Custom field name" and field type "Text".

spec/live/ticket_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,36 @@ def valid_attributes
110110
it_should_be_readable :tickets, :recent
111111
end
112112

113+
describe "custom fields" do
114+
before do
115+
@ticket = ZendeskAPI::Ticket.create(client, {
116+
subject: "live spec subject for custom fields test",
117+
description: "live spec description for custom fields test"
118+
})
119+
end
120+
121+
after do
122+
@ticket&.destroy!
123+
end
124+
125+
it "can write and read custom fields" do
126+
@ticket.custom_field["Custom field name"] = "Custom field value"
127+
@ticket.save!
128+
129+
@ticket.reload!
130+
expect(@ticket.custom_field["Custom field name"]).to eq("Custom field value")
131+
end
132+
133+
it "raises ArgumentError for non-existent fields" do
134+
expect { @ticket.custom_field["This field does not exist"] }.to raise_error(ArgumentError)
135+
end
136+
137+
it "stores custom fields metadata on a client" do
138+
_custom_field_value = @ticket.custom_field["Custom field name"]
139+
expect(@ticket.account_data[:custom_fields]["Custom field name"]).to eq(9961714922394)
140+
end
141+
end
142+
113143
describe ".incremental_export" do
114144
let(:results) { ZendeskAPI::Ticket.incremental_export(client, Time.at(1023059503)) } # ~ 10 years ago
115145

0 commit comments

Comments
 (0)