我目前正在将 Grape API 与 Rails 一起用于我们的 API(用于数据库的 Postgresql)。我是一名全职作为全栈开发人员的初级开发人员,所以我对我缺乏解释这个问题的经验表示歉意。
目前我正在尝试生成“员工”及其相应“地址”的报告。现在每个员工可以有多个地址。
所以我想做的是发出一个请求来获取多个员工及其相应的地址。我仍然想检索没有地址的员工,因此我需要一个 LEFT OUTER JOIN。问题是我需要此连接的条件。例如,有时我可能需要在 GET 请求中发送地址的“id”,以便它会响应所有员工,但只响应我请求的地址。此外,还会有其他地址和员工过滤器,例如仅返回在特定日期处于活动状态的员工和地址。
我只是不确定如何做到这一点,我所做的一切似乎都不起作用,我认为这与 Grape API 或一般轨道的工作方式有关。当我尝试 LEFT OUTER JOIN 时,它仍然没有给我正确的记录,我认为这是因为在葡萄实体中,它在暴露它时对 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 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 方法。我认为在 ONE Request 中执行此操作而不是在单独的 API 调用中获取嵌套数据是一个很好的解决方案。