【问题标题】:How to count current level missed_days?如何计算当前级别missed_days?
【发布时间】:2015-05-01 04:32:42
【问题描述】:

我们怎么能这样称呼<%= habit.current_level.missed_days %>,我们只从current_level调用missed_days,而不是习惯上的所有missed_days(只是大致了解我们想要什么)。

例如,如果选中了两个框,则在习惯索引中调用 <%= habit.missed_days %> 将显示 2,如果选中了八个框,它将显示 8,但这里的目标是即使选中了 8 个框:

它仍然只会在索引中显示2 罢工,因为我们试图仅从当前级别计算missed_days。

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

我们在等级和习惯表中有t.integer "missed_days", default: 0。

missed_days 的大部分逻辑都可以追溯到它的控制器:

class DaysMissedController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]

  def create
    habit = Habit.find(params[:habit_id])
    habit.missed_days = habit.missed_days + 1
    habit.save!
    level = habit.levels.find(params[:level_id])
    level.missed_days = level.missed_days + 1
    level.save!
    head :ok # this returns an empty response with a 200 success status code
  end

  def destroy
    habit = Habit.find(params[:habit_id])
    habit.missed_days = habit.missed_days - 1
    habit.save!
    level = habit.levels.find(params[:level_id])
    level.missed_days = level.missed_days - 1
    level.save!
    head :ok # this returns an empty response with a 200 success status code
  end
end

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

谢谢你的精彩!

【问题讨论】:

  • 关卡模型在哪里?你能补充一下吗?只是想看看关联,MissedDay 也会有所帮助

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


【解决方案1】:

要准确了解您要做什么有点棘手,但希望这会为您指明正确的方向:

看起来您在 Habit 模型上有一个 current_level 方法,但目前它返回当前级别 number 而不是当前级别 model。

所以也许可以将此方法重命名为current_level_number,然后添加一个current_level 方法,例如:

def current_level
  levels[current_level_number - 1] # remember array indexes start at 0
end

那么您应该可以通过habit.current_level.missed_days 获取当前级别的错过天数。

另外,请注意您的 current_level 方法。它在大多数情况下返回一个数字,即 1 到 5,但在特定情况下返回一个字符串“Mastery”。像这样返回不同类型的 I 方法可能会给您带来麻烦。


更多细节:当你养成这个习惯时,看起来你已经设置了 5 个级别:

def save_with_current_level
  self.levels.build
  self.levels.build
...

所以这些将是 levels[0]、levels[1] 到 levels[4]

在您的DaysMissedController 中,您正在更新有关习惯本身和其中一个级别的错过天数,所以我假设这是您想要掌握的当前级别的 days_missed 计数。

您的 current_level 方法根据 n_days 返回一个介于 1 和 5 之间的级别编号,因此当用户处于我们想要的习惯的级别 1 时 levels[0],级别 2 时,levels[1] 等等。

【讨论】:

  • 感谢 Mikej 的帮助!如果您不介意放纵我一秒钟,我对您的代码感到困惑。减去 -1 将如何创建仅从当前级别计算 missed_days 的能力?这意味着索引中显示的数字将始终为 0、1、2、3?换句话说,索引的数量将反映代表用户所在级别的当前行的复选框。这是更好的解释吗?或者,也许我完全误解了你的答案。在那种情况下,对不起!
  • 我刚刚更详细地更新了答案。可能是我还没有完全理解您要做什么,但请看一下,看看是否有帮助。
  • 谢谢迈克!我终于用你的代码搞定了。你很抱歉让这件事变得比原来要困难得多。我发现我将您的代码添加到错误的索引中,这就是为什么无论我做什么我都没有看到变化:/我最愚蠢的编码动作之一。
  • 请记住,该习惯的级别列表包含 5 个条目,因此如果您在该习惯达到 6 时尝试访问 levels[5],那么这将返回 nil,从而导致您看到的错误。如果n_days 可以超过 99,我建议删除 when 70..99 案例并让 else 案例返回 5。即有人在 70 天或更高的任何天数内保持在 5 级作为最高级别。跨度>
  • 知道了!我意识到我需要在索引中添加一个条件,这样当级别为 nil 时,代码将不会显示,因此删除了错误:) 这样我可以保持我的级别结构并吃掉它
【解决方案2】:

这只是一个假设,因为你没有提到太多的关联,我什至不确定我是否理解你想要什么,但如果我的想法是正确的,我会认为/假设它会像这个

MissedDay.joins(level: {habit: :user})
  .merge(User.where(id: user_id))
  .merge(Habbit.where(id: habbit_id))
  .count

【讨论】:

  • 我的要点有你心中想要解决这个问题的所有代码,但具体来说,习惯和级别模型具有has_many 和belongs_to 关系,后者是该模型中的唯一代码。我应该将代码块放在新的模型方法、视图或控制器中的什么位置?
  • 好吧,可能是missed_days模型,这个方法计算丢失的天数,但它需要user_id和habbit_id
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-27
  • 2012-04-17
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多