Ruby on rails 从当前_水平开始计算天数?
有5个级别 每个级别都有一定的天数,必须经过一定的天数,习惯才能升级到下一个级别(按Ruby on rails 从当前_水平开始计算天数?,ruby-on-rails,ruby,model-view-controller,Ruby On Rails,Ruby,Model View Controller,有5个级别 每个级别都有一定的天数,必须经过一定的天数,习惯才能升级到下一个级别(按n_天细分): 我们如何用类似于的东西从习惯索引中的当前水平调用n_天 例如,如果我们在第3级的50,则习惯指数中会显示第5天 习惯.rb class Habit < ActiveRecord::Base belongs_to :user has_many :comments, as: :commentable has_many :levels serialize :comm
n_天
细分):
我们如何用类似于
的东西从习惯索引中的当前水平调用n_天
例如,如果我们在第3级的50
,则习惯指数中会显示第5天
习惯.rb
class Habit < ActiveRecord::Base
belongs_to :user
has_many :comments, as: :commentable
has_many :levels
serialize :committed, Array
validates :date_started, presence: true
before_save :current_level
acts_as_taggable
scope :private_submit, -> { where(private_submit: true) }
scope :public_submit, -> { where(private_submit: false) }
attr_accessor :missed_one, :missed_two, :missed_three
def save_with_current_level
self.levels.build
self.levels.build
self.levels.build
self.levels.build
self.levels.build
self.save
end
def self.committed_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 current_level_strike
levels[current_level - 1] # remember arrays indexes start at 0
end
def current_level
return 0 unless date_started
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 } - self.missed_days
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
end
class Level < ActiveRecord::Base
belongs_to :habit
end
它的要点:在你的
当前的
方法中,你有两行逻辑,最终代表了n天
的价值。如果要在该方法或case语句之外重用该值,则应将该值存储在实例变量中,或将逻辑移到另一个方法中。如果逻辑只对这个类重要,那么我可能会将它设置为私有方法
class Habit < ActiveRecord::Base
# Existing code ...
private
def committed_wdays
committed.map do |day|
Date::DAYNAMES.index(day.titleize)
end
end
def n_days
((date_started.to_date)..Date.today).count do |date|
committed_wdays.include? date.wday
end - self.missed_days
end
end
类习惯
私有方法可以进一步细化,但希望这能让您了解如何继续提取共享逻辑。我认为您提供的代码比解释问题所需的代码还要多。我建议将问题细化到更具体一点。不过我想我明白了,我也会尽力提供一个答案。谢谢凯文!我将您的方法放在当前_级别(代替我的
=
代码)下,而不是放在private下。似乎有效。你能想到这个替代方案的任何负面影响吗?而且你当前的代码调用所有n_天
,而不是只从当前级别调用,因此,例如,如果我养成了30天的习惯,我不想显示30天,我想显示5天,因为我们进入3级的时间是5天。我说得有道理吗?有可能吗?如果你还在研究这个问题,不包括private
就可以了,但这是一种限制对方法的访问的方法,这些方法只能在类内部使用,不能从其他对象引用。好的,非常感谢您回复我@kevinthompson:)您知道一种方法,我可以直接调用当前级别的中经过了多少天吗?这是你得到的一个艰难的飞跃吗?例如,调用f.current_level
将获得准确的级别编号,因此1-5。调用f.n_days
将给出自养成习惯以来已过去的总天数。调用f.current\u level.n\u days
将给出未定义的方法n\u days
create_table "habits", force: true do |t|
t.integer "missed_days", default: 0
t.text "committed"
t.integer "days_lost", default: 0
t.datetime "date_started"
t.string "trigger"
t.string "target"
t.string "reward"
t.boolean "private_submit"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "order"
end
add_index "habits", ["user_id", "created_at"], name: "index_habits_on_user_id_and_created_at"
add_index "habits", ["user_id"], name: "index_habits_on_user_id"
create_table "levels", force: true do |t|
t.integer "habit_id"
t.integer "days_lost", default: 0
t.integer "missed_days", default: 0
t.integer "current_level"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "levels", ["habit_id"], name: "index_levels_on_habit_id"
class Habit < ActiveRecord::Base
# Existing code ...
private
def committed_wdays
committed.map do |day|
Date::DAYNAMES.index(day.titleize)
end
end
def n_days
((date_started.to_date)..Date.today).count do |date|
committed_wdays.include? date.wday
end - self.missed_days
end
end