【问题标题】:Rails: Post JSON to API Using Rails and HTTParty Not WorkingRails:使用 Rails 和 HTTParty 将 JSON 发布到 API 不工作
【发布时间】:2019-08-18 00:21:45
【问题描述】:

我对 Rails 中的 API 非常陌生,虽然我已经获得了一些关于如何构建 HTTParty 发布请求的帮助,但是我发送的有效负载(数据)不会影响我的 API 数据库

我只想通过我的应用程序的 POST 请求在 API 的数据库中创建一条记录。

即每当我创建一本书时,都会在两个数据库(我的数据库和 API 的数据库上通过我的应用程序的 POST 请求)创建一条记录。

对于将使用 API 的应用程序,我正在使用 HTTParty gem,但请求仅在不影响 API 数据库的情况下运行

这是我的 HTTParty 发布请求代码

@result = HTTParty.post(' https://www.pingme.com/wp-json/wplms/v1/user/register',
    :body => {
                :books => {  
                  :name => '#{name}',
                  :author => '#{author}',
                  :description => '#{description}',
                  :category_id => '#{category_id}',
                  :sub_category_id => '#{sub_category_id}'}.to_json, 
    :headers => { 'Content-Type' => 'application/json', 'Authorization' => '77d22458349303990334xxxxxxxxxx' })

但这不会影响 API 的数据库,而只会影响我的 Rails 应用程序的数据库

这是执行的日志代码

Started POST "/books" for 127.0.0.1 at 2019-03-27 11:51:18 +0100
Processing by BooksController#create as HTML

Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxxxxxxx", "book"=>{"name"=>"veb", "author"=>"vebturejjd", "description"=>"aisiosoijjdkdp", "category_id"=>"text books", "sub_category_id"=>"children"}, "commit"=>"Create Book"}
   (0.1ms)    begin transaction

↳ app/controllers/books_controller.rb:32
      Book Create (0.5ms)  INSERT INTO "books" ("name", "author", "description", "category_id", "sub_category_id", "created_at", "updated_at", "client_id") VALUES (?, ?, ?, ?, ?, ?, ?)  [["name", "vebturejjd"], ["author", "vebturejjd"], ["description", "aisiosoijjdkdp"], ["category_id", "text books"], ["sub_category_id", "children"], ["created_at", "2019-03-27 10:51:18.239045"], ["updated_at", "2019-03-27 10:51:18.239045"]]
      ↳ app/controllers/books_controller.rb:32
       (77.8ms)  commit transaction

我在终端中找不到@result 的任何日志,仍然想知道它是否被跳过或没有在运行时运行,或者有更好的方法。

我需要一些关于如何解析 ruby​​ 以发布到 API 数据库的帮助。

这是我用于创建图书的图书控制器

require 'httparty'

class BooksController < ApplicationController
  include HTTParty

  before_action :set_book, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_admin!, except: %i[show index]
  skip_before_action :verify_authenticity_token

  # GET /books
  # GET /books.json
  def index
    @books = Book.search(params[:keywords]).paginate(:page => params[:page], :per_page => 9).order('created_at DESC')
  end

  # GET /books/1
  # GET /books/1.json
  def show
  end

  # GET /books/new
  def new
    @book = Book.new
  end

  # GET /books/1/edit
  def edit
  end

  # POST /books
  # POST /books.json
  def create
    @book = Book.new(book_params)

    respond_to do |format|
      if @book.save
        format.html { redirect_to @book, notice: 'Book was successfully created.' }
        format.json { render :show, status: :created, location: @book }
      else
        format.html { render :new }
        format.json { render json: @book.errors, status: :unprocessable_entity }
      end
    end

    @result = HTTParty.post(' https://www.pingme.com/wp-json/wplms/v1/user/register',
    :body => {
                :books => {  
                  :name => '#{name}',
                  :author => '#{author}',
                  :description => '#{description}',
                  :category_id => '#{category_id}',
                  :sub_category_id => '#{sub_category_id}'}.to_json, 
    :headers => { 'Content-Type' => 'application/json', 'Authorization' => '77d22458349303990334xxxxxxxxxx' })

  end

  # PATCH/PUT /books/1
  # PATCH/PUT /books/1.json
  def update
    respond_to do |format|
      if @book.update(book_params)
        format.html { redirect_to @book, notice: 'Book was successfully updated.' }
        format.json { render :show, status: :ok, location: @book }
      else
        format.html { render :edit }
        format.json { render json: @book.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /books/1
  # DELETE /books/1.json
  def destroy
    @book.destroy
    respond_to do |format|
      format.html { redirect_to books_url, notice: 'Book was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_book
      @book = Book.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def book_params
      params.require(:book).permit(:name, :author, :description, :category_id, :sub_category_id)
    end
end

我们将不胜感激任何形式的帮助。谢谢。

【问题讨论】:

  • 您能记录下@result 是什么吗?另外,您有什么方法可以查看您发布到的 API 的日志,以查看是否收到了调用?
  • 如果您检查 @result 变量的响应状态和正文,您可能会对正在发生的事情有更多的了解。
  • 我不明白@result 是如何向您展示的。这些变量需要用双引号括起来,而不是单引号才能正确插值,即使这样,“#{name}”也应该是未定义的。 "#{@book.name}" 应该有一个值。此外,您永远不会传递真实性令牌,并且密钥是错误的“book”与“books”。
  • 我已更新问题以明确显示 @result 的日志我目前无权查看我发布到的 API 日志。但是,每当我使用 Postman 测试 API 时,都会得到成功的响应。我需要你的帮助,我被困在这里。谢谢。
  • @oneWorkingHeadphone,感谢您指出这一点,我刚刚意识到整个日志代码仅用于 图书创建操作。对于这种误解,我深表歉意,我对 Ruby on Rails 还很陌生。我已经更新了这个问题。你知道任何更好的方法来解决这个问题,因为我找不到 result 的任何日志。谢谢。

标签: ruby-on-rails json ruby api httparty


【解决方案1】:

@result 永远不会在您的控制器中调用,因为重定向发生在执行到达那里之前。

我会将 HTTP 调用包装在一个方法中,而不是将其分配给实例变量,因为它正在处理事物,而不是分配它们,然后将其带入 format.html {} 块中。像这样的:

def create
  @book = Book.new(book_params)

  respond_to do |format|
    if @book.save
      format.html {
        post_to_api 
        redirect_to @book, notice: 'Book was successfully created.' 
      }
      format.json { render :show, status: :created, location: @book }
    else
      format.html { render :new }
      format.json { render json: @book.errors, status: :unprocessable_entity }
    end
  end
end

private

def post_to_api
  HTTParty.post(' https://www.pingme.com/wp-json/wplms/v1/user/register',
    :body => {
              :books => {  
                :name => "#{@book.name}",
                :author => "#{@book.author}",
                :description => "#{@book.description}",
                :category_id => "#{@book.category_id}",
                :sub_category_id => "#{@book.sub_category_id}"}.to_json, 
    :headers => { 
              'Content-Type' => 'application/json',
              'Authorization' => '77d22458349303990334xxxxxxxxxx'
    }
  )
end

【讨论】:

  • 非常感谢 @oneWorkingHeadphone。 不幸的是,这对我不起作用。我想这是因为在我的表单中没有地方可以调用 post_to_api 操作来创建书籍。也许您可以指定一种在 create books 表单 上调用此操作的方式但是,您的回答帮助我修改了代码以使其正常工作。我将发布我的答案,以便您看到对我有用的解决方案
【解决方案2】:

根据@vincent-rolea 和@oneWorkingHeadphone 的贡献,我找到了解决该问题的有效方法。

这是对我有用的更正的 HTTParty 发布请求。

@results = HTTParty.post(' https://www.pingme.com/wp-json/wplms/v1/user/register',
      :body => {    
                :name => "#{@book.name}",
                :author => "#{@book.author}",
                :description => "#{@book.description}",
                :category_id => "#{@book.category_id}",
                :sub_category_id => "#{@book.sub_category_id}"}.to_json, 
      :headers => { 
                   'Content-Type' => 'application/json',
                   'Authorization' => '77d22458349303990334xxxxxxxxxx'
      }
)

确保执行以下操作以使其正常工作

  1. 在您的应用程序中安装和配置HTTParty gem
  2. 在您希望执行请求的控制器中包含并要求 HTTParty gem
  3. HTTParty gem post 请求传递给该控制器中的实例变量

这是我的控制器中 HTTParty Post 请求的实现

require 'httparty'

class BooksController < ApplicationController
  include HTTParty

  before_action :set_book, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_admin!, except: %i[show index]
  skip_before_action :verify_authenticity_token

  # GET /books
  # GET /books.json
  def index
    @books = Book.search(params[:keywords]).paginate(:page => params[:page], :per_page => 9).order('created_at DESC')
  end

  # GET /books/1
  # GET /books/1.json
  def show
  end

  # GET /books/new
  def new
    @book = Book.new
  end

  # GET /books/1/edit
  def edit
  end

  # POST /books
  # POST /books.json
  def create
    @book = Book.new(book_params)

    respond_to do |format|
      if @book.save
        format.html { redirect_to @book, notice: 'Book was successfully created.' }
        format.json { render :show, status: :created, location: @book }
      else
        format.html { render :new }
        format.json { render json: @book.errors, status: :unprocessable_entity }
      end
    end

    @results = HTTParty.post(' https://www.pingme.com/wp-json/wplms/v1/user/register',
          :body => {    
                    :name => "#{@book.name}",
                    :author => "#{@book.author}",
                    :description => "#{@book.description}",
                    :category_id => "#{@book.category_id}",
                    :sub_category_id => "#{@book.sub_category_id}"}.to_json, 
          :headers => { 
                       'Content-Type' => 'application/json',
                       'Authorization' => '77d22458349303990334xxxxxxxxxx'
          }
    )
  end

  # PATCH/PUT /books/1
  # PATCH/PUT /books/1.json
  def update
    respond_to do |format|
      if @book.update(book_params)
        format.html { redirect_to @book, notice: 'Book was successfully updated.' }
        format.json { render :show, status: :ok, location: @book }
      else
        format.html { render :edit }
        format.json { render json: @book.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /books/1
  # DELETE /books/1.json
  def destroy
    @book.destroy
    respond_to do |format|
      format.html { redirect_to books_url, notice: 'Book was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_book
      @book = Book.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def book_params
      params.require(:book).permit(:name, :author, :description, :category_id, :sub_category_id)
    end
end

就是这样

我希望这会有所帮助。

【讨论】:

  • 此代码与您在问题中发布的代码有何不同?
  • @oneWorkingHeadphone,不同之处在于我调用 HTTParty 发布请求正文键值的方式::name => "#{@book.name}" 而不是 :name => '#{name}' 这是我从你的贡献中得到的。但是,我将我的 HTTParty 发布请求分配给了 books 控制器的创建操作中的一个实例变量,而您为 HTTParty 发布请求定义了一个新操作,当我尝试它时它对我不起作用。非常感谢您的帮助,如果没有您的帮助,我将无法完成此任务。非常感谢。
  • 你的实例变量赋值有调用post请求的副作用。由于在此之后不使用实例变量,因此没有必要。我仍然建议您将其包装在一个方法中,因为当有人返回此代码时,您的意图会更加清晰。
猜你喜欢
  • 1970-01-01
  • 2011-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多