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

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

新規登録して質問してみよう
ただいま回答率
85.46%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Ruby on Rails

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

Q&A

解決済

1回答

1928閲覧

axios 404エラーを解決したいです。

Taka2401

総合スコア8

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Ruby on Rails

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

0グッド

0クリップ

投稿2021/09/11 06:23

編集2021/09/11 09:52

前提・実現したいこと

vueを使い非同期通信でフォロー機能を追加したいです。
既にフォロー機能は実装できているので、フォローボタンのみvueで非同期通信に書き換えたいです。

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

axiosを使い、postを実行したところ404エラーが出ました。

//エラーログ web_1 | Processing by Api::V1::RelationshipsController#create as JSON web_1 | Parameters: {"followed_id"=>1, "relationship"=>{"followed_id"=>1}} web_1 | User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ORDER BY `users`.`id` ASC LIMIT 1 web_1 | ↳ /usr/local/bundle/gems/activerecord-5.2.6/lib/active_record/log_subscriber.rb:98 web_1 | (0.2ms) BEGIN web_1 | ↳ app/models/user.rb:26 web_1 | User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 web_1 | ↳ app/models/user.rb:26 web_1 | (0.3ms) ROLLBACK web_1 | ↳ app/models/user.rb:26 web_1 | Completed 201 Created in 8ms (ActiveRecord: 1.1ms) web_1 | web_1 | web_1 | Started GET "/api/v1/relationships/?followed_id=1" for 172.24.0.1 at 2021-09-11 09:46:32 +0000 web_1 | Cannot render console from 172.24.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 web_1 | web_1 | ActionController::RoutingError (No route matches [GET] "/api/v1/relationships"): web_1 | web_1 | actionpack (5.2.6) lib/action_dispatch/middleware/debug_exceptions.rb:65:in `call' web_1 | web-console (3.7.0) lib/web_console/middleware.rb:135:in `call_app' web_1 | web-console (3.7.0) lib/web_console/middleware.rb:22:in `block in call' web_1 | web-console (3.7.0) lib/web_console/middleware.rb:20:in `catch' web_1 | web-console (3.7.0) lib/web_console/middleware.rb:20:in `call' web_1 | actionpack (5.2.6) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call' web_1 | railties (5.2.6) lib/rails/rack/logger.rb:38:in `call_app' web_1 | railties (5.2.6) lib/rails/rack/logger.rb:26:in `block in call' web_1 | activesupport (5.2.6) lib/active_support/tagged_logging.rb:71:in `block in tagged' web_1 | activesupport (5.2.6) lib/active_support/tagged_logging.rb:28:in `tagged' web_1 | activesupport (5.2.6) lib/active_support/tagged_logging.rb:71:in `tagged' web_1 | railties (5.2.6) lib/rails/rack/logger.rb:26:in `call' web_1 | sprockets-rails (3.2.2) lib/sprockets/rails/quiet_assets.rb:13:in `call' web_1 | actionpack (5.2.6) lib/action_dispatch/middleware/remote_ip.rb:81:in `call' web_1 | actionpack (5.2.6) lib/action_dispatch/middleware/request_id.rb:27:in `call' web_1 | rack (2.2.3) lib/rack/method_override.rb:24:in `call' web_1 | rack (2.2.3) lib/rack/runtime.rb:22:in `call' web_1 | activesupport (5.2.6) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call' web_1 | actionpack (5.2.6) lib/action_dispatch/middleware/executor.rb:14:in `call' web_1 | actionpack (5.2.6) lib/action_dispatch/middleware/static.rb:127:in `call' web_1 | rack (2.2.3) lib/rack/sendfile.rb:110:in `call' web_1 | webpacker (5.4.2) lib/webpacker/dev_server_proxy.rb:25:in `perform_request' web_1 | rack-proxy (0.7.0) lib/rack/proxy.rb:63:in `call' web_1 | railties (5.2.6) lib/rails/engine.rb:524:in `call' web_1 | puma (3.12.6) lib/puma/configuration.rb:227:in `call' web_1 | puma (3.12.6) lib/puma/server.rb:706:in `handle_request' web_1 | puma (3.12.6) lib/puma/server.rb:476:in `process_client' web_1 | puma (3.12.6) lib/puma/server.rb:334:in `block in run' web_1 | puma (3.12.6) lib/puma/thread_pool.rb:135:in `block in spawn_thread'

cocnsole

1xhr.js:184 GET http://localhost:3000/api/v1/relationships/?followed_id=1 404 (Not Found) 2 3createError.js:17 Uncaught (in promise) Error: Request failed with status code 404 4 at createError (createError.js:17) 5 at settle (settle.js:19) 6 at XMLHttpRequest.onloadend (xhr.js:58)

該当のソースコード

//routes.rb Rails.application.routes.draw do devise_for :admins, controllers: { sessions: 'admins/sessions', passwords: 'admins/passwords', registrations: 'admins/registrations', } devise_for :users, controllers: { sessions: 'users/sessions', passwords: 'users/passwords', registrations: 'users/registrations', } devise_scope :user do post 'users/guest_sign_in', to: 'users/sessions#guest_sign_in' end # 追記 namespace :api do namespace :v1, format: 'json' do resources :relationships, only: [:create, :destroy] end end # ========= ユーザー(public)のルーティング ================ scope module: :public do root to: 'camps#index' get '/about' => 'homes#about' resources :users, only: [:index, :show, :edit, :update] do resource :relationships, only: [:create, :destroy] resources :reservations, only: [:index, :show] member do get 'following' get 'followers' get 'favorites' get 'post' end end end
//follows.html.erb <%= javascript_pack_tag 'relationship' %> <%= link_to "#{user.followings.count} フォロー", following_user_path(user), class: "link-color" %><span> | </span> <%= link_to "#{user.followers.count} フォロワー ", followers_user_path(user), class: "link-color" %> <div id="relationship"> <% if current_user.id != user.id %> <Relationship-button :follower-id="<%= current_user.id %>" :followed-id="<%= @user.id %>"></Relationship-button> <% end %> </div>
//RelationshipButton.vue <template> <div> <div v-if="isRelationshiped" @click="deleteRelationship()" class="btn btn-bg follow-followed"> <i class="fas fa-user-minus"></i> フォロー解除 </div> <div v-else @click="registerRelationship()" class="btn btn-bg" style="margin:0;"> <i class="fas fa-user-plus"></i> フォローする </div> </div> </template> <script> import axios from 'axios' import { csrfToken } from 'rails-ujs' axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken() export default { props: ['followerId', 'followedId'], data() { return { relationshipList: [] } }, computed: { count() { return this.relationshipList.length }, isRelationshiped() { if (this.relationshipList.length === 0) { return false } return Boolean(this.findRelationshipId()) } }, created: function() { this.fetchRelationshipByFollowedId().then(result => { this.relationshipList = result }) }, methods: { fetchRelationshipByFollowedId: async function() { const res = await axios.get(`/api/v1/relationships/?followed_id=${this.followedId}`) if (res.status !== 200) { process.exit() } return res.data }, registerRelationship: async function() { const res = await axios.post('/api/v1/relationships', { followed_id: this.followedId }) if (res.status !== 201) { process.exit() } this.fetchRelationshipByFollowedId().then(result => { this.relationshipList = result }) }, deleteRelationship: async function() { const relationshipId = this.findRelationshipId() const res = await axios.delete(`/api/v1/relationships/${relationshipId}`) if (res.status !== 200) { process.exit() } this.relationshipList = this.relationshipList.filter(n => n.id !== relationshipId) }, findRelationshipId: function() { const relationship = this.relationshipList.find((relationship) => { return (relationship.follower_id === this.followerId) }) if (relationship) { return relationship.id } } } } </script>
//RelationshipsController module Api module v1 class RelationshipsController < ActionController::API before_action :authenticate_user! def create current_user.follow(relationships_params) head :created end def destroy current_user.unfollow(params[:user_id]) head :ok end private def relationships_params params.require(:relationship).permit(:user_id, :followed_id) end end end end

試したこと

rails routesでパスの確認

api_v1_relationships POST /api/v1/relationships(.:format) api/v1/relationships#create {:format=>/json/} api_v1_relationship DELETE /api/v1/relationships/:id(.:format) api/v1/relationships#destroy {:format=>/json/}

baseurlの設定

//vue.config.js module.exports = { // ベースURLの設定 baseUrl: 'http://localhost:3000/', publicPath: "/" }

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

windows10 home
Ruby 2.6.3
Ruby on Rails 5.2.6

解決に繋がるヒントを頂けますと幸いです。
よろしくお願いいたします。

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

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

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

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

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

neko_daisuki

2021/09/11 07:06

rails のログはどうなっていますか?
Taka2401

2021/09/11 08:24 編集

ご返信ありがとうございます。 エラーログとルーティングを追記いたしました。
neko_daisuki

2021/09/11 08:30

RelationshipsController の module v1 が小文字になってますね。 それで uninitialized constant Api::V1::RelationshipsController になってるのかもしれません。 V1 にしてみてください。
Taka2401

2021/09/11 08:42

大文字に直してみましたが特に変化ありませんでした。 こちらコントローラーのみ大文字にした方がいいということでしょうか。
neko_daisuki

2021/09/11 08:48

module や class の名前は定数(先頭が大文字)の必要があります。 RelationshipsController のパスは app/controllers/api/v1/relationships_controller.rb ですか?
Taka2401

2021/09/11 09:06 編集

ありがとうございます。 RelationshipsController のパスは app/controllers/api/v1/relationships.controller.rb で _がありません。
Taka2401

2021/09/11 09:54

コントローラー名に_をつけて修正したところエラーメッセージが変わったので追記しました。 フォローボタンを押すとpostメソッドになるはずが、なぜかエラーログがgetに変わりました。
neko_daisuki

2021/09/11 10:11

POST のあとに vue の registerRelationship の中で fetchRelationshipByFollowedId を呼んでいるので、そのリクエストだと思います。
Taka2401

2021/09/11 11:51

ありがとうございます。 現状、パスの確認を行ってみましたが原因が特定できておりません、 他にエラーの原因として考えられるものをご教授いただけますでしょうか。
neko_daisuki

2021/09/11 12:05

ActionController::RoutingError (No route matches [GET] "/api/v1/relationships"): GET /api/v1/relationships は定義されていません。定義するかリクエストを削除します。 定義する場合 routes.rb resources :relationships, only: [:index, :create, :destroy] relationships_controller.rb class RelationshipsController < ActionController::API def index # 内容を記述 end リクエストを削除する場合 RelationshipButton.vue registerRelationship: async function() { const res = await axios.post('/api/v1/relationships', { followed_id: this.followedId }) if (res.status !== 201) { process.exit() } // ここから下は不要 // this.fetchRelationshipByFollowedId().then(result => { // this.relationshipList = result // }) },
Taka2401

2021/09/11 13:32

ありがとうございます。 indexをルーティングとコントローラーに定義したら無事にエラーが解決できました。 まだ別のエラーが出ていますが、まずは自分でやってみたいと思います。
Taka2401

2021/09/11 14:04

度々すみません。 ベストアンサーにさせていただきたいのですが、調べてもベストアンサーボタンがあるとの事ですが 僕の画面に見当たらず、お伺いしてもよろしいでしょうか。
neko_daisuki

2021/09/11 14:36

ボタンは"質問への追記・修正"では表示されず、"回答"しないと表示されないのだと思います。 今は多分どこかにあります。
Taka2401

2021/09/11 14:38

回答後、表示されました。 最後までご丁寧にありがとうございました。
guest

回答1

0

ベストアンサー

ruby のクラス名やモジュール名は定数を指定します。
定数は大文字から始まります。

API::V1::PostsController

rails では require でファイルを指定せずともクラスやモジュールが読み込まれますが、
そのためには規則に従う必要があります。

詳しくは以下を参照してください。
定数の自動読み込みと再読み込み (Zeitwerk)

投稿2021/09/11 14:33

neko_daisuki

総合スコア2090

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問