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

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

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

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

Ruby on Rails 6

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

Ruby on Rails

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

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

解決済

3回答

1808閲覧

レベルアップシステムを実装したい

kdh

総合スコア26

Ruby

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

Ruby on Rails 6

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

Ruby on Rails

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

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

0グッド

0クリップ

投稿2020/09/29 08:27

編集2020/09/30 06:16

レベルアップ機能を実装するさいのテーブル設計

現在、railsを使ってタスクを完了したら経験値がたまり、レベルアップするアプリを作っている途中なのですがテーブル設計がわからなく、過去の同じような質問などをみて参考にして書いているのですが自分の場合はどうなのだろうかとなかなか進みません。
devisuによりログイン機能がついており、タスクを入力したら一覧に表示し、タスクが完了したら消すことができるツイート投稿型アプリと構造が同じです。
ちなみにその部分までは完成しており、レベルアップ機能を追加で実装しようとしている段階です。
タスクを消したら経験値を手に入れてレベルアップという流れにしたいです。
以下のテーブル設計についてご教授いただけたら幸いです。言語はrubyです。

自分で書いてみたテーブル設計

## users テーブル | Column | Type | Options | | ------------ | ---------- | ----------------------- | | name | string | null: false | | email | string | null: false | | password | string | null: false | | player_level | integer | null: false, default: 1 | | exp | integer | null: false, default: 0 | | level_id | references | foreign_key: true | ## Association - has_many :tasks - belongs_to :level ## tasks テーブル | Column | Type | Options | | ------- | ---------- | ------------------------------ | | content | string | null: false | | point | integer | null: false, default: 1 | | user_id | references | foreign_key: true | ## Association - belongs_to :user ## レベルテーブル | Column | Type | Options | | --------- | ---------- | ------------------------------ | | level | integer | | | threshold | integer | | ## Association - has_many :users

補足情報

userのexpはtaskのpointと連動して経験値をもらえる仕組身にしようとしています。

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

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

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

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

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

m.ts10806

2020/09/29 08:45

タイトル、タグですが、あまりRailsに特化しなくて良いとは思います。確かに名称など制約は受けるでしょうけど、設計段階ではあまり考慮しすぎなくても良いとは思います。
kdh

2020/09/29 08:50

ありがとうございます。タグやタイトルなど修正してみます。
phper.k

2020/09/29 10:46

プログラミング言語やフレームワークはお使いですか? 使っているようであればフレームワーク名も
kdh

2020/09/29 10:54

ありがとうございます。質問に追記しました。
guest

回答3

0

ベストアンサー

Ruby および Ruby on Rails は門外漢なのですが、修正依頼をした行きがかり上、回答します。

Users

  • users テーブルに exp は不要
  • level_id は場合によって不要
ColumnTypeOptions
idintegernull: false, ai
namestringnull: false
emailstringnull: false
passwordstringnull: false
player_levelintegernull: false, default: 1
expintegernull: false, default: 0
level_idreferencesforeign_key: true
  • exp が不要なのは、

sql

1SELECT sum(tasks.point)` FROM users 2LEFT JOIN tasks ON users.id = tasks.user_id 3GROUP BY users.id

で取得可能だし、終了したタスクが増えるたびに、users テーブルを更新する無駄が発生するから。
フレームワークにバンドルされているORMでも取得可能でしょう。

Tasks

ColumnTypeOptions
idintegernull: false, ai
contentstringnull: false
pointintegernull: false, default: 1
user_idreferencesforeign_key: true
is_finishedbooldefault: false

タスクが終了したのかどうかを判定するカラムは不要?(要件次第だからなんともいえないけど。)
タスク完了の日時でも良いと思う。その場合のカラム名は、finished_at とかが適当でしょう。

levels

ColumnTypeOptions
idintegernull: false, ai
level numberinteger
thresholdinteger

合計のポイントからSQLで現在のレベルを判定することもできる。
(Having とか使ってもっと効率的に取得すべきだけど。)
場合によって、users に level_id がいらないと言ったのはこれが理由

sql

1SELECT 2 users.*, 3 sum(tasks.point), 4 (SELECT name FROM levels WHERE threshold <= sum(tasks.point) LIMIT 1) as level 5FROM users, levels 6LEFT JOIN tasks ON users.id = tasks.user_id 7GROUP BY users.id

投稿2020/09/29 11:11

編集2020/09/29 11:12
phper.k

総合スコア3923

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

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

kdh

2020/09/29 11:52

ありがとうございます。SQLの方はSequel Proのクエリで抽出されるものを確認する程度しかやったことがないですが、ターミナルで打ち込んでいくのでしょうか?
phper.k

2020/09/29 12:20

Sequel Proで確認すればいいと思いますよ。
kdh

2020/09/29 12:48

わかりました。ありがとうございます!
kdh

2020/09/30 12:56

質問失礼します。 SELECT sum(tasks.point)` FROM users LEFT JOIN tasks ON users.id = tasks.user_id GROUP BY users.id をSequel Proで確認したところ真ん中の列はNULLでした。これはusersテーブルとtasksテーブルのレコードの数があっていないからなのでしょうか? またrailsでこのSQL文をどのように使ったらいいのでしょうか? rails SQL使い方 で検索しましたが出てこないので質問させていただきます。お時間ある時でいいのでよろしくお願いいたします。
phper.k

2020/10/01 00:18 編集

railsのことはわかりません
guest

0

レベルアップシステムってキーワードで、イベントソーシングって方法をぜひ紹介したくて、回答を書くことにしました。私自身は全く詳しくありませんw

PHPとEventSauceで始めるイベントソーシングアプリケーション

資料内のコードは php ですが、概念だけ見てください^^;
かなり衝撃的です。

投稿2020/09/29 13:11

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kdh

2020/09/29 13:54

学習して2ヶ月なので、phpは初見でしたがここに書かれていることはJavaScriptに似ていますね!内容は難しかったですがw しかし有益な情報ありがとうございます!
guest

0

tasksテーブルのuser_idは、誰が何のタスクを記録するためのものでしょうか?

であれば、テーブルを分割したほうが良いと思います。

tasks テーブル

ColumnTypeOptions
contentstringnull: false
pointintegernull: false, default: 1
task_idinteger

tasks_users テーブル

ColumnTypeOptions
task_idinteger
user_idinteger

投稿2020/09/29 10:05

Kaiser

総合スコア295

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

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

kdh

2020/09/29 10:42

回答ありがとうございます。 tasksテーブルのuser_idはdeviseを導入しているので、各ユーザーとそのユーザーが設定したタスクを紐付けるものです。ユーザがタスクを自分で決めて投稿するような、構造はツイート投稿型のアプリに似ています。 なのでアソシエーションの関係が1対多なのですがそれでも分割した方がよろしいでしょうか? 中間テーブルは多対多のときに使うものだと思っていたもので。。。
Kaiser

2020/09/29 21:56

承知しました。kdh提示されている構造で特に問題無いと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問