Ruby on Rails, интеграция API Zendesk не загружает клиент

Я пытаюсь настроить API Zendesk в своем приложении. Я решил использовать API, созданный Zendesk< /а>

Я настроил объект инициализатора для загрузки клиента.

config/initializers/zendesk.rb

require 'zendesk_api'

client = ZendeskAPI::Client.new do |config|
  # Mandatory:
  config.url = Rails.application.secrets[:zendesk][:url]

  # Basic / Token Authentication
  config.username = Rails.application.secrets[:zendesk][:username]
  config.token = Rails.application.secrets[:zendesk][:token]

  # Optional:

  # Retry uses middleware to notify the user
  # when hitting the rate limit, sleep automatically,
  # then retry the request.
  config.retry = true

  # Logger prints to STDERR by default, to e.g. print to stdout:
  require 'logger'
  config.logger = Logger.new(STDOUT)

  # Changes Faraday adapter
  # config.adapter = :patron

  # Merged with the default client options hash
  # config.client_options = { :ssl => false }

  # When getting the error 'hostname does not match the server certificate'
  # use the API at https://yoursubdomain.zendesk.com/api/v2
end

Это в значительной степени копипаст с сайта, но я решил использовать комбинацию token + username.

Затем я создал служебный объект, которому я передаю объект JSON и создаю билеты. Этот сервисный объект вызывается из контроллера.

app/services/zendesk_notifier.rb

class ZendeskNotifier
  attr_reader :data

  def initialize(data)
    @data = data
  end

  def create_ticket
    options = {:comment => { :value => data[:reasons] }, :priority => "urgent" }
    if for_operations?
      options[:subject] = "Ops to get additional info for CC"
      options[:requester] = { :email => '[email protected]' }
    elsif school_in_usa_or_canada?
      options[:subject] = "SRM to communicate with student"
      options[:requester] = { :email => '[email protected]' }
    else
      options[:subject] = "SRM to communicate with student"
      options[:requester] = { :email => '[email protected]' }
    end
    ZendeskAPI::Ticket.create!(client, options)
  end

  private
  def for_operations?
    data[:delegate] == 1
  end

  def school_in_usa_or_canada?
    data[:campus_country] == "US" || "CA"
  end
end

Но теперь я получаю

NameError - undefined local variable or method `client' for #<ZendeskNotifier:0x007fdc7e5882b8>:
  app/services/zendesk_notifier.rb:20:in `create_ticket'
  app/controllers/review_queue_applications_controller.rb:46:in `post_review'

Я думал, что клиент был тем же, что и в моем инициализаторе конфигурации. Почему-то мне кажется, что это уже другой объект. Я попытался просмотреть их документацию для получения дополнительной информации, но я не понимаю, что это такое?


person TheLegend    schedule 09.06.2016    source источник


Ответы (2)


Если вы хотите использовать client, определенный в инициализаторе, вам нужно сделать его глобальным, изменив его на $client. В настоящее время вы настроили его как локальную переменную.

person danielrsmith    schedule 09.06.2016
comment
Да, я думаю, что если бы это была одна и та же переменная, они бы сделали ее глобальной переменной в документации, верно? Или они настраивают клиент в том же файле, который затем используют ZendeskAPI::Ticket.create! вызов действия. Я также немного устал от создания глобальной переменной из конфигурации, это хорошая практика? - person TheLegend; 09.06.2016
comment
Я думаю, что в их документации предполагается, что вы помещаете конфигурацию клиента в ту же область, в которой вы ее выполняете. Это хорошая практика - использовать глобальную переменную, я не считаю это ужасной практикой для такого рода вещей. Я видел, как это делается довольно часто с использованием Redis в инициализаторе Rails. Другой вариант — создать службу, которую вы можете вызвать, чтобы получить клиента. client = ZendeskService.client - person danielrsmith; 09.06.2016

Я использовал немного другой способ инициализации клиента, скопировав из этого примера приложение rails с помощью стандартного гема Zendesk API: https://github.com/devarispbrown/zendesk_help_rails/blob/master/app/controllers/application_controller.rb

Как заметил Дэниелсмит, переменная client выходит за рамки. Вместо этого вы могли бы иметь такой инициализатор:

config/initializers/zendesk_client.rb:

class ZendeskClient < ZendeskAPI::Client
  def self.instance
    @instance ||= new do |config|
      config.url = Rails.application.secrets[:zendesk][:url]
      config.username = Rails.application.secrets[:zendesk][:username]
      config.token = Rails.application.secrets[:zendesk][:token]
      config.retry = true
      config.logger = Logger.new(STDOUT)
    end
  end
end

Затем верните клиент в другом месте с помощью client = ZendeskClient.instance (сокращенно для краткости):

приложение/услуги/zendesk_notifier.rb:

class ZendeskNotifier
  attr_reader :data

  def initialize(data)
    @data = data
    @client = ZendeskClient.instance
  end

  def create_ticket
    options = {:comment => { :value => data[:reasons] }, :priority => "urgent" }
    ...
    ZendeskAPI::Ticket.create!(@client, options)
  end
  ...
end

Надеюсь это поможет.

person jpalmieri    schedule 13.06.2016
comment
Это действительно элегантное решение. Спасибо друг :) - person TheLegend; 14.06.2016