Rails LEFT OUTER JOIN索引请求与Grape Entity

时间:2016-09-15 01:32:17

标签: ruby-on-rails grape-entity

我目前正在使用Grape API和Rails一起使用我们的API(Postgresql for the DB)。我是一名初级开发人员,全职担任全栈开发人员,所以我为解释这个问题缺乏经验而道歉。

目前我正在尝试生成一份“员工”的报告。及其相应的地址'现在每个工作人员都可以有很多地址。

所以我想做的是向GET多个员工提出一个请求及其相应的地址。我仍然想要检索没有地址的员工,因此我需要一个LEFT OUTER JOIN。问题是我需要加入此条件的条件。例如,有时我可能需要发送' ID' GET请求中的地址,以便它将响应所有STAFF,但仅响应我请求的地址。此外,还有其他地址和员工过滤器,例如仅返回在特定日期有效的员工和地址。

我只是不确定如何做到这一点,我所做的一切似乎都不起作用,而且我认为这与Grape API或一般的rails如何工作有关。当我尝试LEFT OUTER JOIN时,它仍然没有给我正确的记录,我认为这是因为在Grape Entity中它在暴露它时在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 Entity(我认为这是实现它的方法,因为Grape Entity会自己进行查询以检索嵌套数据?)。感谢您对我的方法的任何建议,谢谢:)

以下是我的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调用中获取嵌套数据是一个很好的解决方案。

0 个答案:

没有答案