How can we integrate t.integer :missed
with t.text :committed
so that
when a User checks off he
:missed
3:committed
days in a:level
he has to restart the:level
?for each
:missed
day he checks off, an additional:committed
day is added back into the:level
so that he must make it up before advancing?
Each habit has 5 levels before "Mastery"
is achieved!
class Habit < ActiveRecord::Base
belongs_to :user
before_save :set_level
acts_as_taggable
serialize :committed, Array
def self.comitted_for_today
today_name = Date::DAYNAMES[Date.today.wday].downcase
ids = all.select { |h| h.committed.include? today_name }.map(&:id)
where(id: ids)
end
def levels
committed_wdays = committed.map { |day| Date::DAYNAMES.index(day.titleize) }
n_days = ((date_started.to_date)..Date.today).count { |date| committed_wdays.include? date.wday }
case n_days
when 0..9
1
when 10..24
2
when 25..44
3
when 45..69
4
when 70..99
5
else
"Mastery"
end
end
private
def set_level
self.level = levels
end
end
I'm guessing we would have to distinguish :missed
from :missed
here depending on what level it is referring to.
habits/_form.html.erb
<label> Missed: </label>
<div>
<label> Level 1: </label>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
</div>
<div>
<label> Level 2: </label>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
</div>
<div>
<label> Level 3: </label>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
</div>
<div>
<label> Level 4: </label>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
</div>
<div>
<label> Level 5: </label>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
<%= f.check_box :missed %>
</div>
habits_controller.rb
class HabitsController < ApplicationController
before_action :set_habit, only: [:show, :edit, :update, :destroy]
before_action :logged_in_user, only: [:create, :destroy]
def index
if params[:tag]
@habits = Habit.tagged_with(params[:tag])
else
@habits = Habit.all.order("date_started DESC")
@habits = current_user.habits
end
end
private
def habit_params
params.require(:habit).permit(:missed, :left, :level, :date_started, :trigger, :target, :positive, :negative, :tag_list, :committed => [])
end
end
_create_habits.rb
class CreateHabits < ActiveRecord::Migration
def change
create_table :habits do |t|
t.integer :missed
t.integer :level
t.text :committed
t.datetime :date_started
t.string :trigger
t.string :target
t.string :positive
t.string :negative
t.references :user, index: true
t.timestamps null: false
end
add_foreign_key :habits, :users
add_index :habits, [:user_id, :created_at]
end
end
:committed
works perfectly, but right now :missed
serves no purpose. Please help me add the appropriate logic to integrate :missed
with :committed
.
Thank you so much for your time!
UPDATE
@Dimitry_N's answer doesn't achieve either 1) or 2) of this question as much as I've tried to make it work. Maybe you'll have a better luck incorporating his logic. With his answer I also get this error: How to fix level.rb to work with :committed days?