前提・実現したいこと
プログラミング初心者です。どなたか教えてください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