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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

0回答

479閲覧

ActiveRecord::StatementInvalid エラー  ランキング機能を実装したい

ty_tech

総合スコア1

Ruby on Rails 6

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

1クリップ

投稿2020/09/23 05:43

編集2020/09/24 05:55

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 %>

参考にしているサイトです

Qiita1

Qiita2

現在考えているコントローラの記述ですと、下記のエラーが出ます

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に投稿イメージを含めたい理由:ユーザーと投稿イメージの整合性が取れるようにしたいため)

初歩的な内容でお恥ずかしいですが、ご教示頂きたくお願い致します。

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

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

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

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

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

no1knows

2020/09/24 05:03

テーブルにどのようなカラムがあるか、質問を編集して、追記ください。 またcatch_sizeとは何のことでしょうか?
ty_tech

2020/09/24 06:00

ご連絡ありがとうございます! ・テーブルにどのようなカラムがあるか → テーブルを追記致しました。 ・catch_sizeとは何のことでしょうか? → 釣った魚のサイズ= catch_sizeとしております。 サイズの合計でランキングをつけたいと思って、現在取り組んでおります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問