首页 > 解决方案 > 文件未在创建时附加,但在 zendesk 更新时附加

问题描述

工作流程应该是用户应该能够将文件附加到 zendesk 票证的评论中,无论它是新票证还是现有票证。

目前将文件附加到现有票证的评论中效果很好。但是,如果您查看 create 操作,就能够附加文件而言,它什么也不做。它不会引发错误,只是不会附加文件。我确定这是我的代码流动的方式,但无法弄清楚。

require_dependency 'zen_support/application_controller'

module ZenSupport
  class TicketsController < ApplicationController
    include SmartListing::Helper::ControllerExtensions
    helper  SmartListing::Helper

    before_action :authenticate_user!, except: :zen_update
    before_action :set_new_ticket, only: [:new, :create]
    before_action :get_ticket, only: [:show, :edit, :update, :zen_update]
    before_action :authorize_ticket, except: :zen_update

    rescue_from ZendeskAPI::Error::NetworkError, with: :network_error

    def new
      respond_to do |format|
        format.js
      end
    end

    def index
      if zen_list_type == 'datatable'
        @tickets = tickets
      else
        smart_listing
      end
      respond_to do |format|
        format.html
        format.js
      end
    end

    def create
      if(!@ticket.valid? && (@ticket.errors.keys - [:zendesk_id]).present?)
        # test if ticket is invalid beyond just missing zendesk_id
        raise ActiveRecord::RecordInvalid.new @ticket
      else
        ActiveRecord::Base.transaction do
          @zendesk_ticket.save!
          upload_to_zendesk(params[:comment], params[:attachments])
          @ticket.zendesk_id = @zendesk_ticket.id
          @ticket.status = @zendesk_ticket.status
          @ticket.save!
          smart_listing

          flash.now[:success] = "Your help request was successfully submitted.\n
          Your support ticket number is ##{@zendesk_ticket.id}.\n\n
          You should receive a confirmation email shortly.\n\n
          Thank you!"
        end
      end
    rescue Exception => exception
      flash.now[:error] = exception.to_s
      @zendesk_ticket.delete if @zendesk_ticket.id
      render :new
    end

    def show
      render action: :edit
    end

    def update
      respond_to do |format|
        format.js do
          # don't save over comment, just use the field for validation
          upload_to_zendesk(params[:comment], params[:attachments])
          @zendesk_ticket.update(ticket_update_params)
          if @ticket.valid? && @zendesk_ticket.save! && @ticket.update(updated_at: Time.now)
            flash.now[:success] = "Your help request was successfully updated.\n
            Your support ticket number is ##{@zendesk_ticket.id}.\n\n
            You should receive a confirmation email shortly.\n\n
            Thank you!"
          else
            flash.now[:error] = if @ticket.errors.present?
              @ticket.errors.full_messages.join "\n"
            else
              'There was a problem sending out your request.'
            end
            render action: :edit
          end
        end
      end
    end

    def zen_update
      ZenSupport::Ticket.find_by(
        zendesk_id: params[:id]
      )&.update(zen_update_params)

      render nothing: true
    end

    def network_error
      flash.now[:error] = 'There was a network error connecting to the Zendesk API. Try again later.'
      render 'network_error'
    end

    private

    def upload_to_zendesk(comment_body, files)
      @zendesk_ticket.comment = { value: comment_body }
      Array(files).each do |file|
        @zendesk_ticket.comment.uploads << file
      end
    end

    def tickets
      ZenSupport::Ticket.where user: current_user
    end

    def smart_listing
      smart_listing_create(
        :support_tickets,
        tickets,
        partial: 'zen_support/tickets/list',
        array: tickets.count != 0
        # we want to use array: true if there are records present because it pre-renders the activerecord
        # objects so we can do sorting on the encrypted field 'subject'. BUT, if there are no records, 
        # then array: true gives us a pagination error
      )
    end

    def ticket_params
      {
        subject: subject,
        comment: comment,
        zendesk_id: zendesk_id,
        zendesk_submitter_id: submitter_id,
        ticket_type: ticket_type,
        priority: priority,
        tags: tags,
        user: current_user
      }
    end

    def zendesk_ticket_params
      {
        subject: subject,
        type: ticket_type,
        comment: { value: comment },
        submitter_id: submitter_id,
        requester_id: requester_id,
        priority: priority,
        tags: tags
      }
    end

    def ticket_update_params
      {
        comment: {
          body: params[:comment],
          author_id: zendesk_user.id
        }
      }
    end

    def zen_update_params
      {
        zendesk_id: zendesk_id,
        status: @zendesk_ticket.status,
        priority: @zendesk_ticket.priority,
        updated_at: @zendesk_ticket.updated_at
      }
    end

    def subject
      params.dig :zen_support_ticket, :subject
    end

    def comment
      params.dig :zen_support_ticket, :comment
    end

    def zendesk_id
      @zendesk_ticket.id
    end

    def tags
      [
        *params.dig(:zen_support_ticket, :tags),
        *ZenSupport.configuration.options[:support_ticket_attributes][:static_tags]
      ]
    end

    def ticket_type
      params.dig(:zen_support_ticket, :ticket_type).to_s.downcase
    end

    def set_new_ticket
      @zendesk_ticket = ZendeskAPI::Ticket.new(
        zen_client, zendesk_ticket_params
      )
      @ticket = ZenSupport::Ticket.new(ticket_params)
    end

    def get_ticket
      @zendesk_ticket = ZendeskAPI::Ticket.find!(
        zen_client,
        id: params[:id]
      )
      @ticket = ZenSupport::Ticket.find_by!(zendesk_id: params[:id])
    end

    def priority
      (params.dig(:zen_support_ticket, :priority) || ZenSupport.configuration.options[:support_ticket_attributes][:default_priority]).downcase
    end

    def submitter_id
      zendesk_user.id
    end

    def requester_id
      zendesk_user.id
    end

    def user_params
      params.require(:zen_support_user).permit(tags: [])
    end

    def zendesk_user
      @zendesk_user ||= (get_zendesk_user || create_zendesk_user)
    end

    def get_zendesk_user
      zen_client.users.search(
        query: "email:#{zen_current_user.email}"
      ).first
    end

    def create_zendesk_user
      ZendeskAPI::User.create(
        zen_client,
        email: zen_current_user.email,
        name: zen_current_user.full_name,
        tags: user_tags
      )
    end

    def user_tags
      ZenSupport.configuration.user_setup[:static_tags]
    end

     def authorize_ticket
      authorize Ticket
    end
  end
end

标签: ruby-on-railsrubyzendeskzendesk-api

解决方案


尝试将这一行添加到您的创建方法中

def create
  if(!@ticket.valid? && (@ticket.errors.keys - [:zendesk_id]).present?)
    # test if ticket is invalid beyond just missing zendesk_id
    raise ActiveRecord::RecordInvalid.new @ticket
  else
    ActiveRecord::Base.transaction do
      @zendesk_ticket.save!
      upload_to_zendesk(params[:comment], params[:attachments])
      @zendesk_ticket.save!
      ...

推荐阅读