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

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

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

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

Ruby on Rails

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

Q&A

1回答

2794閲覧

ランキング機能実装 

tomoharu

総合スコア107

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2017/04/14 12:00

現状コード:
当方rails 初心者です。

やりたいこと:
現在、自分が描いた漫画を投稿して、みんなで読めるようなwebアプリを作成しています。
そして、その漫画一つ一つにいいねをつけることができ、そのいいねの数によってランキングされるという機能を実装中です。

エラーコード: index.html.erbで発生
undefined method `front_cover' for [1, 1]:Array

現状コード:

ruby

1#Comics_controller 2class ComicsController < ApplicationController 3 before_action :authenticate_user! ,only: [:show, :search] 4 def index 5 like_ranking = Like.group(:comic_id).count 6 @comic_ranking = like_ranking.sort_by{|_, v| -v } 7 end 8end 9

ruby

1#Likes_controller 2def create 3 @comic_liked = Comic.find(params[:id]) 4 @comic_liked.likes.find_or_create_by(user_id: params[:user_id]) 5 @comic_liked.update(like: @comic_liked.like+1) 6 redirect_to :controller => 'comics', :action => 'index' 7 end

ruby

1#index.html.erb 2<% @comic_ranking.each do |like| %> 3 <tr> 4 <td><%= image_tag like.front_cover.to_s %></td> 5 <td><%= like.title %></td> 6 <td><%= like.author %></td> 7 </tr> 8 <% end %> 9<table> 10 <thead> 11 <tr> 12 <th>作品表紙</th> 13 <th>作品タイトル</th> 14 <th>作者</th> 15 </tr> 16 </thead>

ruby

1#Comic.rb 2class Comic < ActiveRecord::Base 3 has_many :users, through: :likes 4 has_many :likes, dependent: :destroy 5 mount_uploader :front_cover, FrontCoverUploader 6end

ruby

1#Like.rb 2class Like < ActiveRecord::Base 3 belongs_to :comic, counter_cache: :like 4 belongs_to :user 5end

質問:エラーコード解消法を教えてください。
ハッシュデータがレシーバだからメソッドが使えないのかと思ったのですが、お時間がある時にお聞かせ願えればと思います。足りないコードがあればすぐに対応いたします。

宜しくお願い申し上げます。

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

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

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

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

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

guest

回答1

0

ハッシュデータがレシーバだからメソッドが使えないのかと思ったのですが

その通りです
comicだったものをlikeに置き換えたところでそのまま動くわけがありません
そもそも@comic_rankingは[comic_id,like_count]という配列の配列であって
comicで表されていたActiveRecordとは全然違うものです。
def index
@comic_ranking=Comic.joins(:likes).references(:likes).group(:comic_id).order("count(likes.id dsec"))
end

ruby

1<% @comic_ranking.each do |comic|%> 2 <tr> 3 <td><%= image_tag comic.front_cover.to_s %></td> 4 <td><%= comic.title %></td> 5 <td><%= comic.author %></td> 6 </tr> 7 <% end %> 8<table> 9 <thead> 10 <tr> 11 <th>作品表紙</th> 12 <th>作品タイトル</th> 13 <th>作者</th> 14 </tr> 15 </thead>

とりあえずこれで、エラーは出ませんが、n+1問題が発生してコミックが増えた時、非常に重くなるでしょう。

N+1問題に対応しました
携帯からの更新なので見苦し買ったらすみません。

投稿2017/04/14 17:18

編集2017/04/15 08:54
moke

総合スコア2241

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

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

tomoharu

2017/04/15 08:31

ご回答ありがとうございます。言われた通りにやってみたのですが、ランキングされず、特定のコミックしかランキング画面に出てこないようになってしまいました。 変更したものは以下です。 <%@comic_ranking.each do |comic_id, like_count| %> <% comic = Comic.find_by(comic_id) %> お時間がある時にご教授いただければと思います。 補足情報として、likeテーブルの中で、comic_idの数が一番多いコミックがランキング上位にしたいと思っています。 何卒よろしくお願いいたします。
moke

2017/04/15 08:40 編集

@comic_ranking = like_ranking.sort_by{|_, v| -v } があっているかは検証していないのですが... とりあえず。comic_id,like_countが入れ替わっているかもしれないので。 @comic_ranking.each do |comic_id,like_count| を @comic_ranking.each do |like_count,comic_id| して見てください
moke

2017/04/15 08:53 編集

回答を修正しました、内容が変わっています。 一応両方試して下さい
tomoharu

2017/04/15 15:09

ありがとうございます。やってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問