Rails初心者です。
現在、Railsでランキング機能を作成しております。
いろいろ調べてみたものの辿り着けず、ご質問させて頂きました。
実現したいこと
ランキングを表示させる際に、Tournament_IDに対して投稿された、Postデータ(カラム名:catch_sizeの合計値)に関連しているUserデータ(カラム名:nickname, image)を表示させたいです。
Postモデル
class Post < ApplicationRecord belongs_to :user belongs_to :tournament, optional: true end
Userモデル
class User < ApplicationRecord has_many :tournaments, dependent: :destroy has_many :entries has_many :entry_tournaments, through: :entries, source: :tournament has_many :posts, dependent: :destroy end
Tournamentモデル
class Tournament < ApplicationRecord belongs_to :user has_many :entries has_many :posts def check_confirming errors.delete(:confirming) self.confirming = errors.empty? ? '1' : '' end # トーナメントにエントリーしているか判断するメソッド def entry_completed_by?(user) entries.where(user_id: user.id).exists? end end
posts_controller.rb (現在考えている記述)(追記2現在のコントローラを記述しています)
def ranks @tournament = Tournament.find(params[:tournament_id]) @ranks = User.joins(:posts) .select("sum(posts.catch_size) as total_size ,posts.user_id ,posts.tournament_id ,nickname ,RANK () OVER (PARTITION BY posts.user_id, posts.tournament_id order by sum(posts.catch_size) desc) as rank_number") .where(tournament_id: @tournament) .group("posts.tournament_id, posts.user_id") .order('sum(catch_size) desc') end
posts_controller.rb (当初行なっていた記述)
@tournament = Tournament.find(params[:tournament_id]) sum = Post.where(tournament_id: @tournament).group(:user_id).order('sum(catch_size) DESC').sum(:catch_size) @ranks = sum.values
app/views/posts/ranks.html.erb
※ コントローラができていないと思い、未記述で申し訳ございません。
<% @ranks.each.with_index(1) do |rank,i| %> </p><%= "第#{i}位 #{rank}cm" %></p> <% end %>
参考にしているサイトです
現在考えているコントローラの記述ですと、下記のエラーが出ます
ActiveRecord::StatementInvalid in Posts#ranks Showing /Users/tanahashiyasuhiro/Desktop/fishing_app/app/views/posts/ranks.html.erb where line #1 raised: PG::UndefinedColumn: ERROR: column users.tournament_id does not exist LINE 1: ..."posts" ON "posts"."user_id" = "users"."id" WHERE "users"."t... ^
追記:1 関連テーブルを追加しました
schema.rb
create_table "posts", force: :cascade do |t| t.string "fish_image" t.string "fish_name" t.float "catch_size" t.float "weight" t.string "range" t.integer "user_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.integer "tournament_id" end create_table "tournaments", force: :cascade do |t| t.date "date" t.string "fishing_ground" t.string "fishing_style" t.string "condition" t.string "fish_name" t.string "keeper_size" t.string "some_fish" t.text "comment" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.integer "user_id" end create_table "users", force: :cascade do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.string "nickname" t.string "image" t.string "main_field" t.string "main_target" t.string "max_size" t.text "comment" t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end
追記:2
コントローラとviewを変更したらエラーはなくなりました。
posts_controller.rb (現在のコントローラ)
def ranks @tournament = Tournament.find(params[:tournament_id]) @ranks = @tournament.posts.joins(:user).group("users.id", "users.nickname").order('sum_catch_size desc').sum(:catch_size) end ※上記で取得できた内容です → { [user_id, user_nickname] => "sum_catch_size" } 2つデータが入っているとこんな取得の仕方です → {[2, "Aくん"]=>95.5, [1, "Bくん"]=>90.5}
app/views/posts/ranks.html.erb
<% @ranks.each.with_index(1) do |(nickname,sum_size),i| %> </p><%= "第#{i}位 #{sum_size}cm" %></p> <p><%= nickname[1] %></p> <% end %>
catch_sizeの合計値の大きい順に並べ変えて、「合計値」と「ユーザー名」は取得できました。
ただ、投稿されたpostのイメージ画像が含まれていません。
完成イメージを貼ります
「質問」(追加質問になってしまい申し訳ございません。現在は以下の内容に悩んでおります)
@ranks内に追加で投稿イメージを含めることは可能でしょうか?それとも分けて取得した方が良いでしょうか?
(@ranksに投稿イメージを含めたい理由:ユーザーと投稿イメージの整合性が取れるようにしたいため)
初歩的な内容でお恥ずかしいですが、ご教示頂きたくお願い致します。
あなたの回答
tips
プレビュー