【问题标题】:index is getting called instead of show索引被调用而不是显示
【发布时间】:2017-08-08 11:54:38
【问题描述】:

我正在尝试使用 Ruby on Rails 编写 API。在我的控制器类中,index 方法被调用而不是 show。虽然我正在传递参数。

试过这些网址

http://localhost:3000/api/v1/quatertodate/?invoiceStatus=PENDING
http://localhost:3000/api/v1/quatertodate/PENDING
http://localhost:3000/api/v1/quatertodate/:PENDING

在上述所有情况下,我的 index 方法被调用而不是 show

相应的控制器类

module Api
module V1
    class QuatertodateController < ApplicationController

        def index   
            invoices = Invoice.select("*").where("invoiceDate >= ?", @@present_date-90)
            render json: {status: 'SUCCESS', messasge: 'LOADED QUATERLY INVOICES', data: invoices}, status: :ok
        end

        def show
            invoices1 = Invoice.select("*").where("invoiceStatus== ? AND invoiceDate >= ?", params[:invoiceStatus], @@present_date-90)
            #invoices1 = Invoice.find(params[:invoiceStatus])
      #invoices1=Invoice.select("*").where("invoiceStatus= ? and invoiceDate >= ?", params[:invoiceStatus], @@present_date-180)
            render json: {status: 'SUCCESS', messasge: 'LOADED QUATERLY INVOICES', data: invoices1}, status: :ok
        end

    end
end

结束

注意: 注释部分 #invoices1 也不起作用。抛出:

<ActiveRecord::RecordNotFound: Couldn't find Invoice with 'customerId'=>

架构

create_table "invoices", primary_key: "customerId", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1" do |t|
t.string "customerNumber", limit: 12
t.string "customerType", limit: 5
t.string "invoiceType", limit: 5
t.decimal "invoiceAmt", precision: 65, scale: 30
t.string "invoiceStatus", limit: 12
t.datetime "invoiceDate"

可能的 invoiceStatus 值: BILLED 或 PENDING

路线

Rails.application.routes.draw do
namespace 'api' do
    namespace 'v1' do
        resources :invoices
        resources :monthtodate
        resources :quatertodate
        resources :yeartodate
    end
end
end

耙路

我的目标:退回过去 90 天内发票状态为待处理的发票。
我也尝试了 PATCH 请求的 update 方法,而不是 show 但它抛出了这个错误

AbstractController::ActionNotFound:找不到 Api 的操作“更新”:

删除 index 方法会出现以下错误:

ActiveRecord::RecordNotFound: 找不到带有 'customerId'=>" 的发票

我错过了什么?谁能指引我朝着正确的方向前进?我也找不到任何相关文档。

我是 Ruby on Rails 的新手。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 ruby-on-rails-3.2 ruby-on-rails-3.1


    【解决方案1】:

    如果您要遵循正确的 Rails 和 REST 约定,则不会为此使用 show 操作。 show 用于显示一条记录,并使用此格式的 URL api/v1/quartertodate/:id 调用,其中:id 是您要显示的记录的id 的动态变量。在控制器中,它以params[:id] 的形式提供。

    index 用于显示多条记录,即使它不是所有条记录。

    您可以使用索引操作中的if...else 分支来处理此问题。

    def index   
      @invoices = if params[:invoiceStatus].present?
        Invoice.where("invoiceStatus = ? AND invoiceDate >= ?", params[:invoiceStatus], ninety_days_past)
      else
        Invoice.where("invoiceDate >= ?", ninety_days_past)
      end
    
      render json: {status: 'SUCCESS', messasge: 'LOADED QUATERLY INVOICES', data: @invoices}, status: :ok
    end
    
    def show
      @invoice = Invoice.find(params[:id])
      render json: {status: 'SUCCESS', messasge: 'LOADED INVOICE', data: @invoice}, status: :ok
    end
    
    private
    
    def ninety_days_past
      Date.today - 90
    end
    

    注意:您不需要select('*'),您应该为@invoices 使用实例变量,因为如果您切换到JSON API 的模板引擎,它将需要更少的重构。此外,今天的日期不需要全局变量,只需使用内置的Date 库并执行Date.today。要查找 90 天前的日期,您可以创建一个私有方法 ninety_days_past,这样您就不会复制代码。如果您希望在每个控制器中使用此方法,只需直接在您的 ApplicationController 中定义该方法而不是您的 QuatertodateController

    【讨论】:

    【解决方案2】:

    这个 url 将 reuest 索引操作:

     http://localhost:3000/api/v1/quatertodate?invoiceStatus=PENDING
    

    Route next 将字符串 ?invoiceStatus=PENDING 标识为 id 参数。所以它会请求 show 动作。

    http://localhost:3000/api/v1/quatertodate/?invoiceStatus=PENDING
    

    【讨论】:

    • 那么我的问题的正确解决方案是什么?如何正确地将参数传递给 show
    • 将变量传给生成的路径,api_v1_quatertodate_path(@quatertodate),会生成类似localhost:3000/api/v1/quatertodate/1的路由,最后1是记录的id。
    • 您能详细说明一下吗?或者给我一个例子或一些参考资料?
    • 好的,尽力而为。在您的显示操作中,您通过 invoices1 = Invoice.select("*").where("invoiceStatus== ? AND invoiceDate >= ?", params[:invoiceStatus], @@present_date-90).first 获得单条记录。那么如果你请求路径:api_v1_quatertodate_path(invoices1),它会调用show action。
    • 不对,?invoiceStatus=PENDING 等查询字符串不会被解释为 show 操作的 id 参数。
    猜你喜欢
    • 2022-01-20
    • 2014-06-28
    • 2018-04-16
    • 1970-01-01
    • 2019-01-31
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    相关资源
    最近更新 更多