🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails

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

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

Q&A

解決済

1回答

718閲覧

ActionController::UrlGenerationErrorエラーが解決できません

ooaai

総合スコア17

Ruby on Rails

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

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

0グッド

0クリップ

投稿2021/01/03 03:01

編集2021/01/03 03:58

画像のようなエラーが解決できず息詰まっています。
エラーの意味はidが受け取れないという解釈で合っているでしょうか。
指定の仕方かルーティングが間違っているのかと思い、引数をuser.followerにしたりといろいろ試してみましたが解決できませんでした。

フォロー機能を実装中でフォロー数、フォロワー数のリンクをクリックすると一覧ページに飛ぶところです。

イメージ説明
該当のソースコード

<table class='table'> <tr><%= attachment_image_tag(user, :profile_image, :fill, 100, 100, fallback: "no_image.jpg") %></tr> <tr> <th>name</th> <th><%= user.name %></th> </tr> <tr> <th>introduction</th> <th><%= user.introduction %></th> </tr> <tr> <th>follows</th> <th><%= link_to user.follower.count, user_follower_path(user) %></th> </tr> <tr> <th>followers</th> <th><%= link_to user.followed.count, user_followed_path(user) %></th> </tr> </table> <div class='row'> <% if current_user == user %> <%= link_to '',edit_user_path(user), class: "btn btn-outline-secondary btn-block fas fa-user-cog edit_user_#{user.id}" %> <% else %> <% if current_user.following?(user) %> <%= link_to 'フォローを外す', user_relationships_path(user), method: :delete, class: 'btn btn-info' %> <% else %> <%= link_to 'フォローする', user_relationships_path(user), method: :post, class: 'btn btn-success' %> <% end %> <% end %> </div>

このファイルは部分テンプレートでrenderでindexファイルはcurrent_userを指定、showファイルは@user(@user = @book.user)を指定しています。
関連ファイル

routes.rb

Rails.application.routes.draw do devise_for :users resources :users, only: [:show,:index,:edit,:update] do resource :relationships, only:[:create, :destroy] get 'follower/:id' => 'relationships#follower', as: 'follower' get 'followed/:id' => 'relationships#followed', as: 'followed' end resources :books do resources :book_comments, only: [:create, :destroy] resource :favorites, only: [:create, :destroy] end root 'homes#top' get 'home/about' => 'homes#about', as: 'about' end

user.rb

class User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_many :books has_many :book_comments, dependent: :destroy has_many :favorites, dependent: :destroy has_many :follower, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy#フォローしている has_many :followed, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy#フォローされている has_many :follower_user, through: :followed, source: :follower#フォローしている人 has_many :following_user, through: :follower, source: :followed#フォローされている人 #フォローする def follow(user_id) follower.create(followed_id: user_id) end #フォローを外す def unfollow(user_id) follower.find_by(followed_id: user_id).destroy end #既にフォローしているかの確認 def following?(user) following_user.include?(user) end attachment :profile_image, destroy: false validates :name, length: {maximum: 20, minimum: 2}, uniqueness: true validates :introduction, length: {maximum: 50} end

user_controller.rb

class UsersController < ApplicationController before_action :ensure_correct_user, only: [:update] def show @user = User.find(params[:id]) @books = @user.books @book = Book.new end def index @users = User.all @book = Book.new end def edit @user = User.find(params[:id]) if @user.id != current_user.id redirect_to user_path(current_user) end end def update if @user.update(user_params) redirect_to user_path(@user), notice: "You have updated user successfully." else render "edit" end end private def user_params params.require(:user).permit(:name, :introduction, :profile_image) end def ensure_correct_user @user = User.find(params[:id]) unless @user == current_user redirect_to user_path(current_user) end end end

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

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

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

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

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

guest

回答1

0

ベストアンサー

エラーの意味はidが受け取れないという解釈で合っているでしょうか。

その通りです。
エラー文が読めているので、あと一歩と感じました。

おそらくですが、user_follower_path()には、idを直接指定する必要がありそうな気がします。
たとえば私がよく使うのは、user_follower_path(id: user.id)のような書き方なのですが、これでなおりそうでしょうか?


xxxxx_path()の引数として、railsの参考書ではよくモデルのインスタンス(今回でいえばuser)を渡す例が挙げられていますが、これは、中の動作がわかりにくいです。

実際には、モデルのインスタンスから必要な値を自動で抽出するロジックがrailsに実装されていて、その処理に適合するようなデータを引数として渡さない限り上手く動いてくれません。

なので、その処理をrailsに任せるのではなく、自分で書いてしまう方法を回答例として挙げてみました。

投稿2021/01/03 03:19

編集2021/01/03 03:20
siruku6

総合スコア1382

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

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

ooaai

2021/01/03 03:32 編集

回答ありがとうございます! 試してみたのですがエラー文の下の記述がNo route matches {:action=>"follower", :controller=>"relationships", :user_id=>#<User id: 1, email: "maki@a", name: "aa", introduction: "", profile_image_id: nil, created_at: "2020-12-30 03:56:35", updated_at: "2020-12-30 08:03:03">}, missing required keys: [:id] から No route matches {:action=>"follower", :controller=>"relationships", :id=>1}, missing required keys: [:user_id] に変わっただけでエラーは直りませんでした...
siruku6

2021/01/03 03:39 編集

>required keys: [:user_id] user_idも必要ということであれば、user_idも渡さないといけないですね... ちなみにですが、ここで言われている`id`とは何のidでしょうか? user_idが別途必要になるのであれば、idは何かほかのidかと思いますので、そちらを引数idに渡しましょう
ooaai

2021/01/03 03:55

required keys: に記述されているところが足りないということですか??初歩的な質問ですみません..見方も曖昧なもので;; ユーザのフォローしている人、フォローされている人の一覧をそれぞれ表示させたいので、どのユーザが/の という部分を引数で指定しようとしています。
siruku6

2021/01/03 04:01 編集

今わかっていることは、`user_follower_path()`というメソッドには少なくとも id と user_id を渡さなければいけない状態になっているということです。 user_idはuserのidかと思います。 では、それ以外の別にidが必要になるとすると、何のidを渡すことを想定しているのでしょうか?という質問でした。 >ユーザのフォローしている人、フォローされている人の一覧 フォロワーなどはおそらく複数ですし、user has_many follower, followed が記載されており、user.follower という記述でリスト取得が可能ですので、おそらくこれらのidは必要ないはずです。 そうすると、user_id以外に必要になるidとはなんでしょうか? もしかしたら、routingが間違っている可能性もあるかもしれません(idが不要である可能性)
ooaai

2021/01/03 04:10

めちゃくちゃ丁寧にありがとうございます! ルーティングの記述ミスを考え、idを削除したみたら<%= link_to user.follower.count, user_follower_path(user) %>で解決しました!! ユーザごとに一覧を出したかったのでルーティングにidが必要なのかなと考えていましたがそんなことないんですね。
siruku6

2021/01/03 04:14

解決してよかったです! >ユーザごとに一覧を出したかったのでルーティングにidが必要なのかなと考えていましたがそんなことないんですね。 今回は、`resources :users, .... do`というブロックの中に`get 'follower/....`というルーティングを書いていますよね。 そうすると、その時点でuserのidは自動で必須になります。 `resouces :objects do` で囲んだら、特定のobjectに紐づくアクションへのルーティングをを作成することになるので、覚えておくとよいかもしれません。 (私もここはわかりにくくて理解するまで時間がかかりました)
ooaai

2021/01/03 04:48

そんな仕組みがあるんですねって言いたいんですけどまだよく分かってないのでもうちょっと調べてみようと思います!ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問