【问题标题】:ruby on rails call external api and show resultsruby on rails 调用外部 api 并显示结果
【发布时间】:2020-06-29 21:06:19
【问题描述】:

我正在尝试调用 API(喜欢 https://jsonplaceholder.typicode.com/)。这个想法很简单,单击按钮以显示 res,但我在实现它时遇到了麻烦。我下面的只是调用该函数的按钮,并希望在控制台中打印它。

错误:

enter code here No route matches [POST] "/dashboard/fetch_action"

路线

resources :dashboard do
 collection do
   get :fetch_action
 end
end

dashboard_controller.er

require 'faraday'

def index
end

def fetch_action
    response = Faraday.get 'https://jsonplaceholder.typicode.com/posts/1'
    puts response
    # return response 
end

index.html.erb

    <%= button_to "fetch action", fetch_action_dashboard_index_path, class: "btn btn-warning" %>

谢谢

编辑:

路线:

Rails.application.routes.draw do

  devise_for :users
  
  devise_scope :user do
    root to: 'devise/sessions#new'
  end

  get 'dashboard' => 'dashboard#index'
  get '/dashboard/fetch-action', to: 'dashboard#fetch_action', as: 'dashboard_fetch_action'
  get '/user' => 'dashboard#index', :as => :user_root

end

搜索路线

    new_user_session GET    /users/sign_in(.:format)                                                                 devise/sessions#new
             user_session POST   /users/sign_in(.:format)                                                                 devise/sessions#create
     destroy_user_session DELETE /users/sign_out(.:format)                                                                devise/sessions#destroy
        new_user_password GET    /users/password/new(.:format)                                                            devise/passwords#new
       edit_user_password GET    /users/password/edit(.:format)                                                           devise/passwords#edit
            user_password PATCH  /users/password(.:format)                                                                devise/passwords#update
                          PUT    /users/password(.:format)                                                                devise/passwords#update
                          POST   /users/password(.:format)                                                                devise/passwords#create
 cancel_user_registration GET    /users/cancel(.:format)                                                                  devise/registrations#cancel
    new_user_registration GET    /users/sign_up(.:format)                                                                 devise/registrations#new
   edit_user_registration GET    /users/edit(.:format)                                                                    devise/registrations#edit
        user_registration PATCH  /users(.:format)                                                                         devise/registrations#update
                          PUT    /users(.:format)                                                                         devise/registrations#update
                          DELETE /users(.:format)                                                                         devise/registrations#destroy
                          POST   /users(.:format)                                                                         devise/registrations#create
                     root GET    /                                                                                        devise/sessions#new
                dashboard GET    /dashboard(.:format)                                                                     dashboard#index
   dashboard_fetch_action GET    /dashboard/fetch-action(.:format)                                                        dashboard#fetch_action
                user_root GET    /user(.:format)                                                                          dashboard#index
       rails_service_blob GET    /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET    /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
       rails_disk_service GET    /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT    /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
     rails_direct_uploads POST   /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create
           
                                                                                     

index.html.eb

<%= link_to "fetch action", dashboard_fetch_action_path, class: "btn btn-info" %>

<%= @response %>

fetch-action.html.erb

<%= @response %>

dashboard_controller

def index
end

def show
end

def fetch_action
    uri = URI('https://jsonplaceholder.typicode.com/posts/1')
    req = Net::HTTP.get(uri)
    @response = JSON.parse(req)
end

错误(当点击 link_to 重定向到仪表板/获取操作时出现以下错误):

DashboardController#show is missing a template for this request format and variant. request.formats: ["text/html"] request.variant: [] NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.

【问题讨论】:

  • 为什么在控制器中使用“puts”而不是“respond_to”?
  • fetch_action方法需要返回一个json值,所以最后一行应该是render json: response
  • button_to 元素需要生成一个 GET 请求以匹配您配置的路由。所以添加方法::进入button_to参数。

标签: ruby-on-rails ruby api model-view-controller jsonplaceholder


【解决方案1】:

故障排除和设置路线

首先,在您的终端中,运行rake routes 以打印出您应用中的路线。在此处发布该输出。但是您需要检查该命令的输出,以检查您在按钮中使用的fetch_action_dashboard_index_path - 这是正确的路径吗?

我认为不是。还有一种更简单的方法来声明一条路线。您对路由中的资源声明所做的是为仪表板控制器的索引、显示、创建、更新和删除操作配置路由。您的 routes.rb 文件中的以下行将仅设置 fetch_action 路由并将其命名为“dashboard_fetch_action”

get '/dashboard/fetch-action', to: 'dashboard#fetch_action', as: 'dashboard_fetch_action'

创建指向该路线的链接

第二;使用 link_to 而不是 button_to 来确保您发出 GET 请求。您正在应用的 btn 类将把该链接设置为看起来像一个按钮,a 标记在语义上比 button 更正确(因为你想 GET)所以使用:

&lt;%= link_to "fetch action", dashboard_fetch_action_path, class: "btn btn-warning" %&gt;

渲染动作结果

最后确保您在app/views/dashboard/fetch_action.html.erb 中有一个文件,该文件会将 API 响应呈现为 HTML。此内容(或类似内容)将实现这一目标。

&lt;%= @response =&gt;

并且,在仪表板控制器中的 fetch_action 操作中。代替response = Faraday...,使用@response = Faraday...。这样response 对象就可以在视图 HTML 中被访问(这就是 @ 表示的意思)

def fetch_action
    @response = Faraday.get 'https://jsonplaceholder.typicode.com/posts/1'
end

【讨论】:

  • 太棒了,非常感谢!我在同一当前页面中渲染时遇到问题?我更改了操作方法而不是返回到render @response(并在视图中添加了响应`)但这似乎没有显示任何内容
  • 你没有renderreturn你的回复。您将其设为“实例变量”,因此可以在视图中使用它。阅读rubyguides.com/2019/03/ruby-scope-binding,我会更新答案以更具体。
  • 虽然您不需要以return 结束您的操作,并且您不需要以render 结束它们,但在我上面的示例中,rails 假设我想要一个标准的respond_to堵塞。这有点神奇。
  • 我也试过了,没有返回并使用即时变量,但是它仍然重定向(显然是由于路由,所以我添加了:remote =&gt; true,这就是点击后它不显示的地方。我查看了 link_to 的文档,但也找不到任何可行的方法?我最新的方法是删除路径并通过添加控制器和操作来做到这一点 &lt;%= link_to "fetch action", controller: "dashboard", action: "fetch_action"%&gt;
  • 您采用上述方法增加了复杂性 - 您难以理解的复杂性,它并不能为您解决问题。当您添加 remote: true 时,您是在告诉 Rails 渲染 app/views/dashboard/fetch_action.js.erb 请注意 js 而不是 html - 这可能不是您想要的,当然也不是您为自己设置的服务。
【解决方案2】:

您是否尝试将模板重命名为 fetch_action.html.erb

据我所知,Rails 希望模板名称与动作名称相匹配,这可能是 fetch_action,因为 Ruby 方法不能包含破折号 -。破折号用于减法,这就是它在方法名称中无效的原因。

【讨论】:

  • 是的,我让它工作了!虽然我希望它在索引页面(当前页面)中显示响应
  • 如果这是您问题的解决方案,请将其标记为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-21
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多