NoMethodError: undefined method `submission' for HTTParty

NoMethodError: undefined method `submission' for HTTParty

我目前正在开发一个 Rails 应用程序,我试图在其中向 FormStack API 提交表单。请求如下所示。

这是请求的样子:

POST /api/v2/form/12345/submission.json HTTP/1.1
Host: www.formstack.com
Authorization: Bearer YOUR_APP_OAUTH_TOKEN
Accept: application/json
Content-Type: application/json

field_12345=Example&field_12346=Answer

我正在尝试在我创建的库上使用 Httparty 来实现这一点,以便向此 API 服务发出请求。

module FormStack

 class Form
    include HTTParty
    attr_reader :form_id
    base_uri "https://www.formstack.com/api/v2"

    def initialize
      @access_token = ENV.fetch('FORMSTACK_ACCESS_TOKEN')
      @form_id      = ENV.fetch('FORMSTACK_FORM_ID')
    end

    def create_form
      self.class.get(relative_uri, headers: headers)
    end

    def submission
      self.class.post(create_submission_uri, headers: headers, query: query)
    end

    private

    def relative_uri
      "/form/#{@form_id}/field.json"
    end

    def create_submission_uri
      "form/#{@form_id}/submission.json"
    end

    def headers
      {
        "Accept" => "application/json",
        "Content-Type"  => "application/json",
        "Authorization" => "Bearer #{@access_token}"
      }
    end

    def query
      {
        "field_66563890" => "blah",
        "field_66563757" => "something"
      }
    end
  end
end

控制器

class FormsController < ApplicationController
  def display_form
    @form = FormStack::Form.new().create_form
  end

  def create
    @form.submission
    redirect_to 'localhost:3000'
  end
end

这是路线

get '/forms/display_form', to: 'forms#display_form'
post '/forms/submit', to: "forms#create"

首先,我有一些通用的 ruby 东西要给你:

  1. 当您调用 FormStack::Form.new().create_form 时,您实际上不需要 .new 之后的 () -- ruby 知道调用不带参数的方法,即使您排除parens.
  2. 我不太确定你是如何从 FormsController::create 调用 FormsController::display_form,但现在我假设你正在使用魔法。

总之,继续我的回答。正如您的错误消息所述,该错误与您在没有 submission 方法的对象上调用 submission 有关。有了这些知识,我们就可以看看 Object 你在这一行中调用的提交是什么:

@form.submission

您似乎在 @form 上呼叫 submission。好吧,让我们去看看你在哪里声明@form:

@form = FormStack::Form.new().create_form

让我们将该声明分解为多个部分。首先,使用 FormStack::Form.new(),您正在创建 FormStack::Form 的新实例。到目前为止,一切都很好。 FormStack::Form 上定义了一个 submission 方法。但是随后,您在其上调用 create_form 。那么,让我们看看 create_form 做了什么:

def create_form
  self.class.get(relative_uri, headers: headers)
end

create_form调用HTTParty提供的方法,getget方法returns一HTTParty::ResponseObject。因此,让我们再次解析您设置 @form 的行。分解一下,你在做什么是这样的:

@form = FormStack::Form # This line sets the variable to a constant
@form = @form.new # This line sets the variable to be an instance of FormStack::Form
@form = @form.create_form # This line sets @form to be an instance of HTTParty::Reponse

如您所见,最后我们将 @form 设置为 HTTParty::Reponse 的实例而不是 FormStack::Form,并且由于没有 submission 方法HTTParty::Response 这就是您收到错误的原因。

基于此探索,我们可以看到解决方法是将 @form 设置为 FormStack::Form object,我们可以通过更改 display_form 行动是:

def display_form
  @form = FormStack::Form.new
  @form.create_form
end