railsでprogateのような、レッスンをクリアすると経験値がたまりレベルアップする
というのと似ている概念のレベルアップ機能を作りたいです。
現在練習で作っているアプリで、「ユーザーが本を購入するとその本の著者ごとにスコアがゲットできて、その著者に対してゲットしたスコアの合計が次のレベルの閾値を超えたらそのレベルに昇格」というような機能をアプリにつけたいのですが、レベルアップの際のロジックが想定できず、実装が止まってしまっています。
なお、progateのようなレベルアップ機能と言いましたが、レベル名は数値ではなくstringで、レベルの名前や閾値、レベルの段階は著者ごとに可変を想定しております。
例えば、ユーザーAが著者Aの本を購入した場合、その著者に対して、閾値が0である"にわか"というレベルがまず付与され、その後、著者Aの本をまた購入してスコアが100を超えた場合、閾値が100である"准にわか"というレベルが付与され、それがさらに閾値170に到達すると次のレベル、400に到達すると次のレベルなど、どんどん続いていく。また、ユーザーAが著者Bの本を購入した場合、閾値が0である"にわか"というレベルがまず付与され、その後、著者Bの本を購入してスコアが120を超えた場合、閾値が120である"ノーマルファン"というレベルが付与され、閾値200のレベル、閾値500のレベルへとレベルアップしていく、というような感じです。
テーブル構造は、以下の通りです。
レベルの名前、閾値、レベルの段階はあらかじめ私がデータベースに入れておき、それぞれ購入時に中間テーブルを作成し紐づかせるという構造です。
ある著者の本の一番最初の購入でparent_purchasesテーブルとchild_purchsesテーブルが作成され、その二つのテーブルで特定の著者への合計スコアを出します。parent_purchasesテーブルは最初の購入時のみ作成され、以降の同一著者の本の購入はchild_purchasesテーブルのみの作成となります。
create_table "parent_purchases", force: :cascade do |t| t.integer "user_id" t.integer "author_id" t.integer "member_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "child_purchases", force: :cascade do |t| t.integer "parent_purchase_id" t.integer "amount" t.datetime "created_at", null: false t.datetime "updated_at", null: false end ↓レベルの名前のテーブル create_table "level_names", force: :cascade do |t| t.string "name" t.integer "author_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end #中間テーブル create_table "parent_purchase_level_names", force: :cascade do |t| t.integer "parent_purchase_id" t.integer "level_name_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end #閾値のテーブル create_table "thresholds", force: :cascade do |t| t.integer "qualified_amount" t.integer "author_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end #中間テーブル create_table "level_name_thresholds", force: :cascade do |t| t.integer "threshold_id" t.integer "level_name_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end #レベルの段階のテーブル create_table "level_stages", force: :cascade do |t| t.integer "stage_number" t.integer "author_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end #中間テーブル create_table "level_name_stages", force: :cascade do |t| t.integer "level_name_id" t.integer "level_stage_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end
current_user.parent_purchase.child_purchases.pluck(:amount).inject(:+)
でその著者に対しての合計スコアを出し、それに基づいて次のレベルまであと〜スコア
、や、そのスコアの閾値を超えたらレベルアップ
、というビジネスロジックが思い浮かびません。
現在のユーザーの著者に対するレベルや何段階目なのかはすぐに出せ、現在のスコア
から次のスコアの閾値
までを計算して、超えたらレベルアップ
というのを実装したいのですが、まず次のスコア
までをどうやって出せば良いのかわかりません。このテーブル構造で実装できますでしょうか?それともそもそもテーブルの構造がおかしいのでしょうか?
長くなりましたが解答よろしくお願いいたします。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。