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

时间:2015-02-19 00:08:00

标签: ruby-on-rails ruby

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

当用户养成习惯时,他会将:date_started放入其中:committed以及:committed做习惯。

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

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

据我所知,我当前的代码应该有效,但由于某些原因,无论用户为:committedclass 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添加什么,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都不会改变。

20150130201715_create_habits.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

habit.rb

<%= f.label "Committed to:" %>&nbsp;
<%= f.collection_check_boxes :committed, Date::DAYNAMES, :downcase, :to_s %>

habits_controller.rb

<td><%= habit.levels %></td>
<td><%= habit.committed.map { |d| d.titleize[0,3] }.join ', ' %></td>
<b><%= habit.date_started.strftime("%m-%d-%Y") %></b>

习惯_形式

{{1}}

习惯指数

{{1}}

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

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

3 个答案:

答案 0 :(得分:1)

我认为您唯一的问题是,您在committed字段中以小写形式存储了日期名称,然后尝试将它们与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 } 在标题中包含它们。否则,逻辑看似合理。

这应该有效:

{{1}}

答案 1 :(得分:0)

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

答案 2 :(得分:0)

究竟是什么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: []