【问题标题】:Counting the Days from the current_level?从 current_level 计算天数?
【发布时间】:2015-05-06 03:51:51
【问题描述】:

有 5 个级别。

每个级别都有一定的天数,必须经过一定的天数才能让习惯升级到下一个级别(由n_days 细分):

      case n_days     
          when 0..9
            1
          when 10..24
            2
          when 25..44
            3  #Level 3
          when 45..69
            4
          when 70..99
            5
          else
            "Mastery"
         end
      end

我们如何在习惯索引中将当前级别的n_days 称为<%= habit.current_level.n_days.count_off_from_zero_to_show %> 之类的名称?

例如,如果我们专门位于第 3 级的 50,它将在习惯索引中显示第 5 天。

habit.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

level.rb

class Level < ActiveRecord::Base
  belongs_to :habit
end

架构

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"

要点https://gist.github.com/RallyWithGalli/c66dee6dfb9ab5d338c2

【问题讨论】:

  • 我认为您提供的代码超出了解释您的问题所需的数量。我建议将问题提炼得更具体一些。不过我想我明白了,我也会尝试提供答案。

标签: ruby-on-rails ruby model-view-controller


【解决方案1】:

在您的current_level 方法中,您有两行逻辑最终代表n_days 的值。如果您想在该方法或 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

私有方法可以进一步细化,但希望这能让您了解如何继续提取共享逻辑。

【讨论】:

  • 谢谢凯文!我把你的方法放在 current_level 下(代替我的= 代码),而不是把它放在私有下。似乎工作。您能想到该替代方案的任何负面影响吗?
  • 此外,您当前的代码调用所有 n_days 而不是仅从当前级别调用,例如,如果我养成了 30 天的习惯,我不想显示 30,我想显示 5因为我们进入第 3 级还有 5 天。我说得更有意义吗?这可能吗?
  • 如果你还在研究这个,不包括private 很好,但它是一种限制对只能在你的类内部使用而不是从其他对象引用的方法的访问的方法。
  • 好的,非常感谢@kevinthompson 回复我 :) 你知道我可以在current_level 中调用多少天吗?与你所得到的相比,这是一个艰难的飞跃吗?例如,调用 f.current_level 将获得确切的级别编号,因此为 1 - 5。调用 f.n_days 将给出自习惯开始以来经过的总天数。调用f.current_level.n_days 给出未定义的方法n_days
猜你喜欢
  • 2013-03-14
  • 2020-01-18
  • 1970-01-01
  • 2010-10-25
  • 2020-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多