0

私は現在、API (DB の Postgresql) に Rails と一緒に Grape API を使用しています。私はフルスタック開発者としてフルタイムで働いているジュニア開発者なので、この質問を説明する経験が不足していることをお詫びします。

現在、「スタッフ」とそれに対応する「住所」のレポートを生成しようとしています。これで、各スタッフ メンバーは多くのアドレスを持つことができます。

したがって、私がやりたいことは、対応するアドレスを持つ複数のスタッフを取得する 1 つの要求を作成することです。アドレスを持たないスタッフを取得したいので、LEFT OUTER JOIN が必要です。問題は、この結合に条件が必要なことです。たとえば、GET 要求でアドレスの「ID」を送信して、ALL STAFF で応答し、要求したアドレスのみを返す必要がある場合があります。また、特定の日付にアクティブだったスタッフとアドレスのみを返すなど、アドレスとスタッフ用の他のフィルターもあります。

これを行う方法がよくわかりません。私が行っていることはすべてうまくいかないようです。これは、Grape API または一般的なレールの仕組みに関係していると思います。LEFT OUTER JOIN を試しても、正しいレコードが得られません。これは、Grape エンティティで公開時に has_many アソシエーションで奇妙なことを行っているためだと思います。

とにかく、これを十分に説明したいと思います。もっと良いアプローチがあれば教えてください。おそらく、必要なすべてのスタッフと住所を取得するために、複数の個別のリクエストでそれを行う方が良い方法です。

アップデート

コーディング例を提供できなくて申し訳ありません。問題の解決策を思いつくことができましたが、それが良いアプローチかどうかはわかりません。

 module V2
  module Entities
   class StaffEntity < Grape::Entity
    expose :id, :dob, :first_name, :surname, :email_address,
    :contact_number, :job_title, :emerg_first_name, :emerg_surname,
    :emerg_contact_number, :emerg_relationship

    expose :report_addresses, if: { :include_addresses => true }, as:  
    :addresses, using: V2::Entities::Addresses

    def report_addresses
      addresses = object.addresses
      addresses = addresses.where('addresses.deleted_at IS NULL') unless  options[:date]
      addresses = addresses.where('addresses.created_at <= ? AND (addresses.deleted_at IS NULL OR addresses.deleted_at >= ?)', options[:date].next.midnight, options[:date].next.midnight) if options[:date]
      addresses = addresses.where('addresses.id IN (?)', options[:addresses]) if options[:addresses]
      addresses
    end
   end
  end
 end

report_addresses メソッドのコードが乱雑で申し訳ありません。仕事に戻ったら整理しようと思います。したがって、基本的には、代わりに多くの条件付きデータベース クエリを Grape エンティティに移動しました (Grape エンティティはネストされたデータを取得するためにクエリ自体を作成するため、それがその方法だと思いますか?)。私のアプローチに関するアドバイスをいただければ幸いです:)

スタッフエンティティで応答するブドウ API は次のとおりです。

module V2
  module StaffAPI
  class Staff < GrapeApi
    helpers do
      def get_staff
        if params[:id]
          @staff = Staff.where(:organisation => current_organisation.id).find(params[:id])
                     .includes(:addresses)
        else
          @staff = Staff.where(:organisation => current_organisation.id)
                  .where(:deleted_at => nil)
                  .includes(:current_addresses)
          @staff = @staff.active unless params[:date]
          @staff = @staff.where('staff.created_at <= ? AND (staff.deleted_at IS NULL OR staff.deleted_at >= ?)', params[:date], params[:date]) if params[:date]
          @staff = @staff.where(:id => params[:staff]) if params[:staff]
        end
      end
    end

    before do
      authenticated
    end

    resource :staff do
      params do
        optional :id, type: Integer
        optional :include_addresses, type: Boolean
        optional :include_staff_avatar, type: Boolean
        optional :staff, type: Array[Integer]
        optional :addresses, type: Array[Integer]
        optional :organisations, type: Array[Integer]
        optional :date, type: Date
      end

      get do
        get_staff
        return error!('Staff not found', 404) unless @staff
        present @staff, with: V2::Entities::StaffEntity,
                include_addresses:   params[:include_addresses],
                include_staff_avatar: params[:include_staff_avatar],
                addresses: params[:addresses],
                date: params[:date]
       end
     end
   end
 end
end

多くのオプションを渡すことができるように、GET リクエストをできるだけ柔軟にしようとしました。しかし、これが良い RESTFUL アプローチであるかどうかはわかりません。個別の API 呼び出しでネストされたデータを取得するのではなく、1 つの要求でこれを行うことが良い解決策であると考えました。

4

0 に答える 0