如何制作:水平变化基于:承诺天数?

我正在创建一个习惯跟踪应用。

当一个用户创造一个习惯时,他会把它放入:date_started以及他在哪些日子里:committed养成这个习惯。

然后,从以下:date_started开始X :committed天数:date_started习惯移动到后续:level (每个级别的天数在下面的模型中细分)。

换句话说,我们如何使用:committed日子,而不是任何一天,来计算什么:level习惯:level

据我所知,我当前的代码应该可以工作,但由于某种原因,不管用户为:date_started:committed提供什么, :level都不会改变。

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  { 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  []) end end 

习惯_form

    

习惯指数

    

Github : https : //github.com/RallyWithGalli/ruletoday

提前感谢您的专业知识=]

我相信你唯一的问题是你在committed字段中以小写forms存储日期名称,然后尝试将它们与Date::DAYNAMES匹配,它们在标题情况下具有它们。 否则,逻辑似乎是合理的。

这应该工作:

 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 } 

根据您的业务逻辑,有很多方法可以做到这一点。 例如,如果您要解锁每个级别的某些权限,那么您希望以不同于级别仅显示UIfunction的方式处理它。 无论哪种方式,您都可以在:name属性中添加一个级别表,该级别表将保存您的级别名称。 然后你会有一个habit_level表,它将与习惯的外键和级别的外键联接。 当您更新日期时,您会检查天数是否为某个数字,如果是,则在连接表中创建相应级别和习惯的记录。

究竟是什么committed ? 我知道了:

t.text :committed

committed.map { |day| Date::DAYNAMES.index(day) }

这真的没有意义,我不确定这对你有什么用。 看起来你正在存储多天名称,如果是这种情况你应该使用某种类型的数组(字符串或整数)。 然后你可以将n_days设置为简单的committed.length

我将该列更改为t.string :committed, array: true, default: []t.integer :committed, array: true, default: []