如何根据 :committed 天数进行 :level 更改? [英] How to Make :level Change Based on :committed Days?
问题描述
我正在创建一个习惯跟踪应用.
I'm creating a habit tracking app.
当用户养成习惯时,他会将其放入:date_started
以及他:committed
养成习惯的日子.
When a User creates a habit he will put in its :date_started
and which days he is :committed
to doing the habit.
然后在从 :date_started
起经过 X 天的 :committed
天后,习惯会转移到下一个 :level
(每个级别的天数)在下面的模型中细分).
Then after X amount of :committed
days from the :date_started
the habit moves onto the succeeding :level
(amount of days per level are broken down in the model below).
换句话说,我们如何使用 :committed
天而不是任何一天来计算一个习惯处于什么:level
?
In other words, how can we use :committed
days, instead of just any day, to calculate what :level
a habit is on?
据我所知,我当前的代码应该可以工作,但是由于某种原因,无论用户为 :date_started
或 :date_started
输入什么,:level
都不会改变代码>:已提交代码>.
From what I know my current code should work, but for some reason the :level
isn't changing regardless of what a User puts for the :date_started
or :committed
.
20150130201715_create_habits.rb
class CreateHabits < ActiveRecord::Migration
def change
create_table :habits do |t|
t.integer :missed
t.datetime :left
t.integer :level
t.text :committed
t.datetime :date_started
t.string :trigger
t.string :action
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
habit.rb
class Habit < ActiveRecord::Base
belongs_to :user
before_save :set_level
validates :action, presence: true
serialize :committed, Array
scope :missed, -> { where(missed: 1) }
scope :nonmissed, -> { where(missed: 0) }
def levels
committed_wdays = committed.map { |day| Date::DAYNAMES.index(day) }
n_days = (date_started..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
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
@habits = Habit.all.order("date_started DESC")
@habits = current_user.habits
end
def show
end
def new
@habit = current_user.habits.build
end
def edit
end
def create
@habit = current_user.habits.build(habit_params)
if @habit.save
redirect_to @habit, notice: 'Habit was successfully created.'
else
@feed_items = []
render 'pages/home'
end
end
def update
if @habit.update(habit_params)
redirect_to @habit, notice: 'Habit was successfully updated.'
else
render action: 'edit'
end
end
def destroy
@habit.destroy
redirect_to habits_url
end
private
def set_habit
@habit = Habit.find(params[:id])
end
def correct_user
@habit = current_user.habits.find_by(id: params[:id])
redirect_to habits_path, notice: "Not authorized to edit this habit" if @habit.nil?
end
def habit_params
params.require(:habit).permit(:missed, :left, :level, :date_started, :trigger, :action, :target, :positive, :negative, :committed => [])
end
end
习惯_形式
<%= f.label "Committed to:" %>
<%= f.collection_check_boxes :committed, Date::DAYNAMES, :downcase, :to_s %>
习惯指数
<td><%= habit.levels %></td>
<td><%= habit.committed.map { |d| d.titleize[0,3] }.join ', ' %></td>
<b><%= habit.date_started.strftime("%m-%d-%Y") %></b>
Github:https://github.com/RallyWithGalli/ruletoday
预先感谢您的专业知识 =]
Thanks in advance for your expertise =]
推荐答案
我相信您唯一的问题是您在 committed
字段中以小写形式存储日期名称,然后尝试匹配它们带有 Date::DAYNAMES
,它们在标题中.否则,逻辑似乎是合理的.
I believe your only problem is that you're storing the day names in lowercase in the committed
field, and then trying to match them with Date::DAYNAMES
, which has them in title case. Otherwise, the logic seems sound.
这应该有效:
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 }
这篇关于如何根据 :committed 天数进行 :level 更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!