質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

1回答

641閲覧

APIのエンドポイントの叩き方がわからない

masakingu

総合スコア11

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

1グッド

2クリップ

投稿2023/01/23 03:55

前提

APIを使用して、サッカー選手を検索できる機能を作成しています。
固定のURIにリクエスとするとレスレスポンスは返ってきますが、
固定では無いURIにリクエストするとエラーが発生します。

実現したいこと

エラーを解決して、固定のURIにリクエストするのでは無く、名前とシーズンによって検索できるようにしたいです。

発生している問題・エラーメッセージ

名前とシーズンで検索した時のエラーメッセージ

app/controllers/players_controller.rb:60:in `search' Started GET "/players/search?season=2018&player_name=cavani&commit=%E6%A4%9C%E7%B4%A2" for ::1 at 2023-01-22 21:34:10 +0900 Processing by PlayersController#search as HTML Parameters: {"season"=>"2018", "player_name"=>"cavani", "commit"=>"検索"} Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.0ms | Allocations: 2378) URI::InvalidURIError (bad URI(is not URI?): "https://api-football-v1.p.rapidapi.com/v3/players/season&search?/\#{params}"): app/controllers/players_controller.rb:60:in `search'

該当のソースコード

players_controller.rb

class PlayersController < ApplicationController require 'uri' require 'net/http' require 'openssl' require 'json' before_action :set_q, only: %i[search] def index @players = Player.all end def show end def edit end def update respond_to do |format| if @player.update(player_params) format.html { redirect_to player_url(@player), notice: "Player was successfully updated." } format.json { render :show, status: :ok, location: @player } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @player.errors, status: :unprocessable_entity } end end end # DELETE /players/1 or /players/1.json def destroy @player.destroy respond_to do |format| format.html { redirect_to players_url, notice: "Player was successfully destroyed." } format.json { head :no_content } end end def search if player_name = params[:player_name] params = URI.encode_www_form({player_name: @player_name}) #ここのURIでエラー発生 url = URI.parse('https://api-football-v1.p.rapidapi.com/v3/players/season&search?/#{params}') http = Net::HTTP.new(url.host, url.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE request = Net::HTTP::Get.new(url) request["x-rapidapi-host"] = 'api-football-v1.p.rapidapi.com' request["x-rapidapi-key"] = ' API KEY' response = http.request(request) puts response.read_body result = JSON.parse(response.read_body) if result["response"] @player_name = result["response"][0]["player"]["name"] @season = result["response"][0]["statistics"][0]["league"]["season"] @team = result["response"][0]["statistics"][0]["team"]["name"] @age = result["response"][0]["player"]["age"] @natinality = result["response"][0]["player"]["nationality"] #end end end end private def set_q @q = User.ransack(params[:q]) end def set_player @player = Player.find(params[:player_id]) end def player_params params.require(:player).permit(:player_name, :season) end def search_params params[:q]&.permit(:player_name, :season) end end

players_controller.rbの固定のURI

url = URI.parse('https://api-football-v1.p.rapidapi.com/v3/players?team=85&search=cavani')

search.html.erb

<div class="container"> <div class="row"> <div class="col-lg-8 offset-lg-2"> <div class="player"> <%= form_with url: search_players_path, method: :get, local: true do |f| %> <div class="form-group"> <h1>プレイヤー検索</h1> <%= f.text_field :season, class: 'form-control', placeholder: '西暦を入力してください(例: 1997)' %> <div class="search2 "> <%= f.text_field :player_name, class: 'form-control', placeholder: '選手名を入力してください' %> <%= f.submit '検索', class: 'btn btn-primary' %> </div> </div> <% if @player_name.present? %> <%= render 'players/player' %> <% end %> <% end %> </div> </div> </div> </div>

_player.html.erb

<div class="container"> <div class="row"> <div class="col-lg-8 offset-lg-2"> <h1>player</h1> <div> <% if @player_name.present? %> <table> <tr> <td>プレイヤー名</td> <td><%= @player_name %></td> </tr> <tr> <td>西暦</td> <td><%= @season %></td> </tr> <tr> <td>チーム名</td> <td><%= @team%></td> </tr> <tr> <td>年齢</td> <td><%= @age%></td> </tr> <tr> <td>国籍</td> <td><%= @natinality%></td> </tr> </table> <% end %> </div> </div> </div> </div>

試したこと

paramsの部分が間違っていると思うのですが原因がわからないです。

補足情報(FW/ツールのバージョンなど)

API : https://www.api-football.com/documentation-v3#tag/Players/operation/get-players

shinoharat👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuma.inaura

2023/01/23 04:06

変数 @player_name が突如表れてますがこの値って空ではないんでしょうか
guest

回答1

0


変数展開したい場合はシングルクォーテーションではなくダブルクォーテーションを使ってください。

diff

1- url = URI.parse('https://api-football-v1.p.rapidapi.com/v3/players/season&search?/#{params}') 2+ url = URI.parse("https://api-football-v1.p.rapidapi.com/v3/players/season&search?/#{params}")


他の方も指摘していますが、インスタンス変数 @player_name を宣言前に使っている部分があるので、修正します。

diff

1 if player_name = params[:player_name] 2- params = URI.encode_www_form({player_name: @player_name}) 3+ params = URI.encode_www_form({player_name: player_name}) 4 url = URI.parse("https://api-football-v1.p.rapidapi.com/v3/players/season&search?/#{params}")

  • シーズンが検索条件に含まれていないので、含めましょう。
  • プレイヤー名のパラメータ名も間違っているので直しましょう。

diff

1 if player_name = params[:player_name] 2- params = URI.encode_www_form({player_name: player_name}) 3+ params = URI.encode_www_form({ search: player_name, season: params[:season] }) 4 url = URI.parse("https://api-football-v1.p.rapidapi.com/v3/players/season&search?/#{params}")


encode_www_form メソッドが自動でパラメータを & で連結してくれるので、自前で & を付ける必要がありません。
? だけは自分で付け加える必要があります。

diff

1 if player_name = params[:player_name] 2 params = URI.encode_www_form({ search: player_name, season: params[:season] }) 3- url = URI.parse("https://api-football-v1.p.rapidapi.com/v3/players/season&search?/#{params}") 4+ url = URI.parse("https://api-football-v1.p.rapidapi.com/v3/players?#{params}")


変数名が params だと rails がデフォルトで用意しているメソッドと名前が被って不便なので変えましょう。

diff

1 if player_name = params[:player_name] 2 3- params = URI.encode_www_form({ search: player_name, season: params[:season] }) 4+ query_string = URI.encode_www_form({ search: player_name, season: params[:season] }) 5 6- url = URI.parse("https://api-football-v1.p.rapidapi.com/v3/players?#{params}") 7+ url = URI.parse("https://api-football-v1.p.rapidapi.com/v3/players?#{query_string}")

--

以下が最終的な完成図です。

rb

1 if player_name = params[:player_name] 2 query_string = URI.encode_www_form({ search: player_name, season: params[:season] }) 3 url = URI.parse("https://api-football-v1.p.rapidapi.com/v3/players?#{query_string}")

投稿2023/02/02 03:18

shinoharat

総合スコア1676

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masakingu

2023/02/03 18:27

回答ありがとうございます。 上記のように修正したら、URI::InvalidURIErrorは解決しました。 nameとseasonで検索をかけたら、下記のエラーが出ました。 ``` app/controllers/players_controller.rb:81:in `search' Started GET "/players/search?season=2018&player_name=cavani&commit=%E6%A4%9C%E7%B4%A2" for ::1 at 2023-02-03 22:02:22 +0900 Processing by PlayersController#search as HTML Parameters: {"season"=>"2018", "player_name"=>"cavani", "commit"=>"検索"} {"get":"players","parameters":{"search":"cavani","season":"2018"},"errors":{"team":"The League or Team field is required with the Search field.","league":"The League or Team field is required with the Search field."},"results":0,"paging":{"current":1,"total":1},"response":[]} Completed 500 Internal Server Error in 1559ms (ActiveRecord: 132.0ms | Allocations: 11868) NoMethodError (undefined method `[]' for nil:NilClass @player_name = result["response"][0]["player"]["name"] ^^^^^^^^^^): app/controllers/players_controller.rb:81:in `search' ``` 検索フィールドにteamかleagueが入ってないからエラーになっているという解釈であってますかね?
shinoharat

2023/02/04 04:57

ご自身で ``` puts response.read_body ``` と書かれているのですから、まずはそれを確認されてはいかがでしょうか?
shinoharat

2023/02/04 04:59

それから、レスポンスの HTTP ステータスも確認されたほうが良いと思います。 200 OK 以外になってる可能性もありますので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問