我在Rails API控制器中有一个索引方法,这很可怕,如下所示。
我确信还有更多的Ruby或Rails方式可以编写此代码。
该操作支持分页和过滤(通过filter =查询参数),并且还可以提供客户ID,以将返回的内容限制为仅与所提供的客户相关的投标。
我想知道是否应该将客户功能分离到单独的端点? (例如客户/:id /提案)。当然,该端点还需要支持分页和过滤器,因此我认为我可能不会以DRY代码结尾。有没有一种方法(像关注问题一样)可以使该索引代码更简单(即没有所有if...then...else
)?
def index
if params[:page].present?
page = params[:page]
if params[:filter].present?
if params[:customer_id].present?
@proposals = current_user.retailer.proposals.customer(params[:customer_id]).search(params.slice(:filter)).page(page)
else
@proposals = current_user.retailer.proposals.search(params.slice(:filter)).page(page)
end
else
if params[:customer_id].present?
@proposals = current_user.retailer.proposals.customer(params[:customer_id]).page(page)
else
@proposals = current_user.retailer.proposals.page(page)
end
end
render json: @proposals, root: 'proposals', meta: pagination_dict(@proposals)
else
render status: :bad_request, json: { message: "Please supply page parameter" }
end
end
以下是Proposal
模型范围:
default_scope { order("updated_at DESC") }
scope :filter, -> (term) { where("lower(first_name) || ' ' || lower(last_name) || ' ' || lower(email) LIKE ? OR qd_number::text LIKE ?", "%#{term.downcase}%", "%#{term}%") }
scope :customer, -> (customer_id) { where customer_id: customer_id }
答案 0 :(得分:1)
我将从以下内容开始:
def index
if params[:page].present?
@proposals = current_user.retailer.proposals.page(params[:page])
@proposals = @proposals.customer(params[:customer_id]) if params[:customer_id].present?
@proposals = @proposals.search(params.slice(:filter)) if params[:filter].present?
render json: @proposals, root: 'proposals', meta: pagination_dict(@proposals)
else
render status: :bad_request, json: { message: "Please supply page parameter" }
end
end
此外,您可能想在before_action
中处理错误:
before_action :check_required_parameters, only: :index
def index
@proposals = current_user.retailer.proposals.page(params[:page])
@proposals = @proposals.customer(params[:customer_id]) if params[:customer_id].present?
@proposals = @proposals.search(params.slice(:filter)) if params[:filter].present?
render json: @proposals, root: 'proposals', meta: pagination_dict(@proposals)
end
private
def check_required_parameters
return if params[:page].present?
render status: :bad_request, json: { message: "Please supply page parameter" }
end
或者您可能希望更改范围以处理空白值:
# in the model
scope :filter, -> (term) { where("lower(first_name) || ' ' || lower(last_name) || ' ' || lower(email) LIKE ? OR qd_number::text LIKE ?", "%#{term.downcase}%", "%#{term}%") if term.present? }
scope :customer, -> (customer_id) { where(customer_id: customer_id) if customer_id.present? }
# in the controller
def index
if params[:page].present?
@proposals = current_user.retailer.proposals
.customer(params[:customer_id])
.search(params.slice(:filter))
.page(params[:page])
render json: @proposals, root: 'proposals', meta: pagination_dict(@proposals)
else
render status: :bad_request, json: { message: "Please supply page parameter" }
end
end