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

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

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

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

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

Ruby on Rails

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

Q&A

2回答

1362閲覧

Rails Micropostのお気に入り機能2

Tarzan3154

総合スコア7

Ruby

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

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

Ruby on Rails

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

0グッド

0クリップ

投稿2020/09/05 14:33

編集2020/09/23 14:28

前提・実現したいこと

プログラミング初心者です。どなたか教えてくださいm_ _m
Railsで既に作成しておいたTwitterクローンに作成したMicropost(投稿)をUserがお気に入りに登録できる機能を追加することにしました。(お気に入り一覧を表示するページを作成し、ナビバーから自分のお気に入り一覧ページへのリンクをつけ、users#show にそれぞれのUserのお気に入り一覧へのリンクをつける)
https://tarzanposts.herokuapp.com/
※まだ試作段階ですが、アプリのURLになります。(herokuにデプロイしたものですので、表示されるエラー画面は異なります)

###①ユーザー詳細のFavoritesタブのリンクをクリックしても、お気に入り一覧ページに行けない。

###②お気に入りに登録しているMicropostを削除しようとすると、エラーメッセージが表示されて削除できない。(お気に入りに登録していないMicropostは正常に削除できる)
###③_navbar.html.erb で 
Favoritesのhref属性を <%= likes_user_path(@user) %>
にして、ログアウトしてToppages/indexの画面を表示させようとすると、下記のエラー画面が表示されてしまう。(href属性を / にしたら、正常に表示される)

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

1

1NoMethodError in Users#likes 2 3undefined method `email' for #<Favorite:0x00007f61782a2e30> 4 5Extracted source (around line #3): 6module UsersHelper 7 def gravatar_url(user, options = { size: 80 }) 8 gravatar_id = Digest::MD5::hexdigest(user.email.downcase) 9 size = options[:size] 10 "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}" 11 end

2

1ActiveRecord::StatementInvalid in MicropostsController#destroy 2 3Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails (`microposts_development`.`favorites`, CONSTRAINT `fk_rails_98783f2eed` FOREIGN KEY (`micropost_id`) REFERENCES `microposts` (`id`)): DELETE FROM `microposts` WHERE `microposts`.`id` = 2 4 5Extracted source (around line #18): 6def destroy 7 @micropost.destroy 8 flash[:success] = "メッセージを削除しました。" 9 redirect_back(fallback_location: root_path) 10 end

3

1ActionController::UrlGenerationError in Toppages#index 2 3No route matches {:action=>"likes", :controller=>"users", :id=>nil}, missing required keys: [:id] 4 5Extracted source (around line #7): 6 <span class="navbar-toggler-icon"></span> 7</button> 8<a class="navbar-brand" href="<%= likes_user_path(@user) %>">Favorites</a> 9<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"> 10 <span class="navbar-toggler-icon"></span> 11</button>

該当のソースコード

users_controller.rb class UsersController < ApplicationController before_action :require_user_logged_in, only: [:index, :show, :followings, :followers, :likes] def index @users = User.order(id: :desc).page(params[:page]).per(25) end def show @user = User.find(params[:id]) @microposts = @user.microposts.order(id: :desc).page(params[:page]) counts(@user) @favorites = @user.favorites.page(params[:page]) counts(@user) end def new @user = User.new end def create @user = User.new(user_params) if @user.save flash[:success] = 'ユーザを登録しました。' redirect_to @user else flash.now[:danger] = 'ユーザの登録に失敗しました。' render :new end end def followings @user = User.find(params[:id]) @followings = @user.followings.page(params[:page]) counts(@user) end def followers @user = User.find(params[:id]) @followers = @user.followers.page(params[:page]) counts(@user) end def likes @user = User.find(params[:id]) @favorites = @user.favorites.page(params[:page]) counts(@user) end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end
application.html.erb <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Microposts</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script> <script defer src="https://use.fontawesome.com/releases/v5.7.2/js/all.js"></script> </head> <body> <%= render 'layouts/navbar' %> <div class="container"> <%= render 'layouts/flash_messages' %> <%= yield %> </div> </body> </html>
_navbar.html.erb <header class="mb-4"> <nav class="navbar navbar-expand-sm navbar-dark bg-dark"> <a class="navbar-brand" href="/">Microposts</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"> <span class="navbar-toggler-icon"></span> </button> <a class="navbar-brand" href="<%= likes_user_path(@user) %>">Favorites</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse justify-content-end" id="navbarSupportedContent"> <ul class="navbar-nav"> <% if logged_in? %> <li class="nav-item"><%= link_to 'Users', users_path, class: 'nav-link' %></li> <li class="nav-item dropdown"> <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown"><%= current_user.name %></a> <ul class="dropdown-menu dropdown-menu-right"> <li class="dropdown-item"><%= link_to 'My profile', user_path(current_user) %></li> <li class="dropdown-divider"></li> <li class="dropdown-item"><%= link_to 'Logout', logout_path, method: :delete %></li> </ul> </li> <% else %> <li class="nav-item"><%= link_to 'Signup', signup_path, class: 'nav-link' %></li> <li class="nav-item"><%= link_to 'Login', login_path, class: 'nav-link' %></li> <% end %> </ul> </div> </nav> </header>
index.html.erb <% if logged_in? %> <div class="row"> <aside class="col-sm-4"> <%= form_with(model: @micropost, local: true) do |f| %> <div class="form-group"> <%= f.text_area :content, class: 'form-control', rows: 5 %> </div> <%= f.submit 'Post', class: 'btn btn-primary btn-block' %> <% end %> </aside> <div class="col-sm-8"> <%= render 'microposts/microposts', microposts: @microposts %> </div> </div> <% else %> <div class="center jumbotron"> <div class="text-center"> <h1>Welcome to the Microposts</h1> <%= link_to 'Sign up now!', signup_path, class: 'btn btn-lg btn-primary' %> </div> </div> <% end %>
toppages_controller.rb class ToppagesController < ApplicationController def index if logged_in? @micropost = current_user.microposts.build # form_with 用 @microposts = current_user.feed_microposts.order(id: :desc).page(params[:page]) end end end
likes.html.erb <div class="row"> <aside class="col-sm-4"> <div class="card"> <div class="card-header"> <h3 class="card-title"><%= @user.name %></h3> </div> <div class="card-body"> <img class="rounded img-fluid" src="<%= gravatar_url(@user, { size: 500 }) %>" alt=""> </div> </div> <%= render 'relationships/follow_button', user: @user %> </aside> <div class="col-sm-8"> <ul class="nav nav-tabs nav-justified mb-3"> <li class="nav-item"><a href="<%= likes_user_path(@user) %>" class="nav-link <%= 'active' if current_page?(likes_user_path(@user)) %>">Favorites <span class="badge badge-secondary"><%= @count_favorites %></span></a></li> <li class="nav-item"><a href="<%= user_path(@user) %>" class="nav-link <%= 'active' if current_page?(user_path(@user)) %>">Microposts <span class="badge badge-secondary"><%= @count_microposts %></span></a></li> <li class="nav-item"><a href="<%= followings_user_path(@user) %>" class="nav-link <%= 'active' if current_page?(followings_user_path(@user)) %>">Followings <span class="badge badge-secondary"><%= @count_followings %></span></a></li> <li class="nav-item"><a href="<%= followers_user_path(@user) %>" class="nav-link <%= 'active' if current_page?(followers_user_path(@user)) %>">Followers <span class="badge badge-secondary"><%= @count_followers %></span></a></li> </ul> <%= render 'users', users: @favorites %> </div> </div>

試したこと

①に関しては、fovoritesテーブルに"email"というカラムがないからかと思い、emailカラムを作成してみましたが、改善せず。(usersテーブルのmigrationファイル内でemailカラムの行に:null => falseをつけてみても変わりませんでした)
②に関しては、お気に入り機能を実装する前は正常に動作しており、原因分かりませんでした。
⇒microposts_controller.rbの記述等は間違いないでしょうか?

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

DB:MySQL
FW:Ruby on Rails5.2.2
コーディング環境:AWS Cloud9
バージョン管理システム:Git/GitHub
API用サーバー:Heroku

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

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

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

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

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

winterboum

2020/09/05 20:52

沢山ソース載ってますが必要なものがひとつもないです。 modelの関連定義のところを載せてください。 お気に入り一覧のviewとそれを呼ぶcontrollerを載せてください
winterboum

2020/09/06 09:10

もう少しわかり易くしてください 1. 「Favoritesタブのリンクをクリック」 この「Favoritesタブのリンク」はどのcodeのどの部分ですか? 2. クリックした時に行くのは どのcodeのどのactionですか 3. そのaxctionが呼び出すview == エラーが出るview は likes.html.erb ですか? あと、 counts(@user) というのは何をしているのでしょう
winterboum

2020/09/06 09:31

お気に入り と Micropost のモデルの関連定義も確認したい
Tarzan3154

2020/09/06 12:38

1.「Favoritesタブのリンク」は show.html.erb の <%= likes_user_path(@user) %> の部分です。 2.クリックした時に行くのは、userモデルのlikesアクションです。 3.エラーが出るviewは likes.html.erb です。  counts(@user)については、詳細画面でFavorites・Microposts・Followings・Followersに登録している数を表示する為に入れています。
winterboum

2020/09/06 21:39

う〜む、、 予想していた通りの遷移ですね、 それで @user が undefined method `email' for #<Favorite: になるのは解せない。 counts(@user)って@userを使っているだけで、代入などはしていないですよね?codeはhelper に? 質問2の原因はわかっているのですが、その確認のために「お気に入り と Micropost のモデルの関連定義も確認したい」
Tarzan3154

2020/09/07 16:05

counts(@user)については、users_controlloer.rb内で(favoritesならlikesアクションで)代入しています。 users_helper.rbのソースコードも追記していますので、ご確認お願いします。 「お気に入り と Micropost のモデルの関連定義も確認したい」 ⇒「favorite.rb」と「micropost.rb」は載せておりますが、そちらのコードのことではないのでしょうか?
winterboum

2020/09/08 01:51

あ、』見落としてました
Tarzan3154

2020/09/08 09:23

質問3を追加で入れてます。 もしお時間あれば、ご回答よろしくお願い致します。
winterboum

2020/09/08 10:53

codeをそのまま書いていただかないと。 人間語に翻訳すると人によって訳し方が違うから
Tarzan3154

2020/09/08 13:03

「application.html.erb」と「_navbar.html.erb」は一応追記済みですが、 そちらを確認いただいた上での発言ですかね? (私が言葉足らずでコードを追記した旨をコメントしていないことが原因でしたらすみません)
winterboum

2020/09/08 22:53

こーど追記は見落としてました。 で、 何行目あたりなのかがわからないと、探すのこんなんです
Tarzan3154

2020/09/09 02:06

質問しているのは、 _navbar.html.erb の 7行目 Favoritesのhref属性を <%= likes_user_path(@user) %> にして、ログアウトしてToppages/indexの画面(およびMicropost一覧ページ)を表示させようとすると、 上記のエラー画面が表示されてしまうのですが、原因をご教示お願いできないでしょうか?(href属性を / にしたら、正常に表示される)
winterboum

2020/09/09 03:10

@user に値が入ってませんね。 蛇足 <a class="navbar-brand" href="<%= likes_user_path(@user) %>">Favorites</a> ⇓ <%= link_to "Favorites",likes_user_path(@user) , class: "navbar-brand" %>
Tarzan3154

2020/09/10 08:23

@user に値が入ってませんね。 ⇒それは、users_controller.rbのindexアクションを確認すればよろしいでしょうか?
winterboum

2020/09/10 08:45

users_controller.rbのindexアクション から呼び出しているならそうです。 Toppages/indexの画面(およびMicropost一覧ページ)から呼び出しているならそちらのactionです
Tarzan3154

2020/09/14 08:19

色々調べてみましたが、原因分かりませんでした。 「index.html.erb」「toppages_controller.rb」を追記しておりますが、 修正点はありますでしょうか?
winterboum

2020/09/14 09:37

index.html.erb は どのdirのですか? それによって見るべき controllerがちがいます
guest

回答2

0

1に関しては...

gravatar_url の呼び出し側で第一引数に Favorite のインスタンスを渡しているのが原因かと。
実際は User インスタンスを渡すべきです。

こういうときのデバッグ方法は
undefined method 'email' とエラーメッセージが出ているので
そのメソッドを呼び出しているオブジェクト(ここでは user を確認してみるのが良いです。

私なら email の記述がある直前の行に以下を追加します。
p HOGE: user.class

これでログに出力される HOGE な表示を見つけて user オブジェクトのクラスがなんなのかを確認するでしょう

投稿2020/09/21 23:18

naserehari

総合スコア35

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

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

Tarzan3154

2020/09/23 14:31

ご回答ありがとうございます。 確認してみたところ、UserオブジェクトのクラスはFavoriteでした。 likes.html.erbも追記しておりますが、 Userインスタンスを渡すようにするには、どのように修正すればよろしいでしょうか?
guest

0

1の方は現時点で ??? です
2は、
Favorite が belongs_to :micropost になっています。このDB定義を見せて頂くのを忘れましたが、おそらく micropost_id が外部keyになっています。
このため favoriteが残っている状態で相手の micorpostを削除しようとするとエラーになります。
Micropost の has_many :favorites に dependent: :destroy を追加してください

ただ、、、おかしいですね。
has_many :favorites, class_name: 'User'
favorites って Favorit と関連しているのでは?

投稿2020/09/08 03:24

winterboum

総合スコア23567

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

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

Tarzan3154

2020/09/08 06:08

ご回答ありがとうございます。 2に関してはご指摘のとおり、 Micropost の has_many :favorites から class_name: 'User'を削除して dependent: :destroy を追加したら、お気に入りに登録済みの投稿も削除ができるようになりました。 ありがとうございました。
Tarzan3154

2020/09/08 06:13

2だけでも解決できてよかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問