如何修复level.rb来处理:承诺的日子? [英] How to fix level.rb to work with :committed days?

查看:168
本文介绍了如何修复level.rb来处理:承诺的日子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最初我有:承诺工作精美的日子,但是为了适应用户检查他是否错过了一个:committed day我现在收到与有关的代码的错误信息:commit

Originally I had :committed days working beautifully, but upon changing up the models a bit in order to accommodate the User's ability to check off if he missed a :committed day I now get an error message for the code relating to :committed:

未定义的方法to_date为nil:NilClass
行#30 n_days =((date_started.to_date)..日期。今天).count {| date | committed_wdays.include? date.wday}

这段代码来自习惯模型:

This code comes from the habit model:

class Habit < ActiveRecord::Base
	belongs_to :user
	has_many :levels
	has_many :days, through: :levels #for being able to access Habit.find(*).days
	accepts_nested_attributes_for :levels, :days
	before_save :set_level
	acts_as_taggable
	serialize :committed, Array

	def evaluate(user)
    levels.each { |level| level.evaluate }
    user.missed_levels << levels.where(passed: false).ids 
    user.missed_days << days.where(missed: true).ids 
    user.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 levels
			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 }

  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

这背后的逻辑是,用户创建一个习惯他想挑战要实现掌握习惯,他必须完成5级。每个级别都有一定数量的:承诺天,必须在推进之前完成,如上所述,用 n_days 分解。

The logic behind it all is that a User creates a habit he wants to challenge. To achieve "mastery" in the habit he must complete 5 levels. Each level has a certain amount of :committed days that must be completed before advancing, as broken down above with n_days.

用户在_form中提交他希望做的习惯的日子(星期六)。例如他可以选择太阳,wed,sat。那么应用程序应该根据非 :commit n_days c $ c> days(一天中的10次通过它移到第二级)。

The User commits in the _form to what days (Sun thru Sat) he wants to do the habit. For example he could just choose sun, wed, sat. Then the app should only calculate n_days according to non-:missed :committed days (once 10 of those days passes it moves onto the 2nd level).

class Level < ActiveRecord::Base
  belongs_to :habit
  belongs_to :user
  has_many :days

  accepts_nested_attributes_for :days

def evaluate 
  if days.where(missed: true ).count == days_needed 
    update_attributes(passed: false) 
  else 
    update_attributes(passed: true) 
  end 
end

end

class Day < ActiveRecord::Base
	belongs_to :level
	belongs_to :habit
end

class HabitsController < ApplicationController
  before_action :set_habit, only: [:show, :edit, :update, :destroy]
  before_action :logged_in_user, only: [:create, :destroy]

  def index
    if params[:tag]
      @habits = Habit.tagged_with(params[:tag])
    else
      @habits = Habit.all.order("date_started DESC")
      @habits = current_user.habits
    end
  end

  def show
  end

  def new
    @goal = current_user.goals.build
    @habit = current_user.habits.build
    @level = current_user.levels.build
    3.times { @level.days.build }
  end

  def edit
  end

  def create
    @habit = current_user.habits.build(habit_params)
    @levels = @habit.levels
    if  @habit.evaluate(@user)
        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(
      :user_id, 
      :level, 
      :left, 
      :date_started, 
      :trigger, 
      :target, 
      :positive, 
      :negative, 
      :tag_list, 
      :committed => [],
      :levels_attributes => [
      :passed,
      :days_attributes => [
      :missed,:level_id]])
  end
end

<%= simple_form_for(@habit) do |f| %>
  <%= f.error_notification %>

<div class="america">
  <form>
    <div class="committed">
      <%= f.label "Committed to:" %>&nbsp;
      <%= f.collection_check_boxes :committed, Date::DAYNAMES, :downcase, :to_s %>
    </div>
    <p>
    <div class="date-group">
    <label> Started: </label>
      <%= f.date_select :date_started, :order => [:month, :day, :year], class: 'date-select' %>
    </div>
    </p>
    <p>
      <%= f.text_field :trigger, class: 'form-control', placeholder: 'Enter Trigger' %></p>
    <p>
      <%= f.text_field :tag_list, habit: @habit.tag_list.to_s.titleize, class: 'form-control', placeholder: 'Enter Action' %>
    </p>
    <p>
      <%= f.text_field :target, class: 'form-control', placeholder: 'Enter Target' %>
    </p>
    <p>
      <%= f.text_field :positive, class: 'form-control', placeholder: 'Enter Reward' %>
    </p>

  <% 5.times.each_with_index do |number, index| %> 
    <h1>Level <%= index + 1 %></h1>
    <%= f.fields_for :levels do |level| %>
      <%= level.fields_for :days do |day| %>
        <%= day.label :missed %>
        <%= day.check_box :missed %> <br/>
      <% end %>
    <% end %>
  <% end %>


<div class="america2">
  <%= button_tag(type: 'submit', class: "btn") do %>
  <span class="glyphicon glyphicon-plus"></span>
  <% end %>

  <%= link_to habits_path, class: 'btn' do %>
  <span class="glyphicon glyphicon-chevron-left"></span>
  <% end %>

  <%= link_to @habit, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn' do %>
  <span class="glyphicon glyphicon-trash"></span>
  <% end %>
</div>
  
</form>
</div>
<% end %>

<!-- Default bootstrap panel contents -->
<div id="valuations" class="panel panel-default">
  
  <div class="panel-heading"><h4><b>HABITS</b></h4></div>

  <!-- Table -->
  <table>
  <thead>
    <tr>
      <th>Level</th>
      <th>Left</th>
      <th>Strike</th>
      <th>Trigger</th>
      <th>Action</th>
      <th>Target</th>
      <th>Reward</th>
      <th>Days</th>
    </tr>
  </thead>

  <tbody>
    <% @habits.each do |challenged| %>
      <tr>
        <td><%= challenged.level %></td>
        <td><%= challenged.left %></td>
        <td>
        <%= link_to edit_habit_path(challenged) do %>
        <%= [params[:missed]].flatten.length %>
        <% end %></td>
        <td><%= challenged.trigger %></td>
        <td class="category">
          <b><%= raw challenged.tag_list.map { |t| link_to t.titleize, taghabits_path(t) }.join(', ') %></b>
        </td>
        <td><%= challenged.target %></td>
        <td><%= challenged.positive %></td>
        <td class= "committed">
          <%= challenged.committed.map { |d| d.titleize[0,3] }.join ', ' %></td>
      </tr>
    <% end %>
  </tbody>
</table>
</div>

非常感谢您的帮助!

这些代码中的一些代码来自此答案:如何整合:错过的日期与:级别?,这搞砸了与这个答案有效:如何制作:基于:承诺日的级别更改

Some of this code came from this answer here: How to integrate :missed days with :level? which messed up what worked with this answer: How to Make :level Change Based on :committed Days?

推荐答案

似乎 date_started 是您的 Habit model,可能是一个数据库列,在 date_started 中有NULL。打开你的Rails控制台,看看是否这样:

It appears that date_started is an attribute of your Habit model, probably a database column, and that there are NULLs in date_started. Open up your Rails console and see if this is the case with:

Habit.where(date_started: nil).count

如果您希望 date_started 不应该为空,添加一个验证来确保是这样。一旦你测试了将该空格保存到该列中的代码,那么验证错误就会指出你的错误。

If you expect that date_started should never be null, add a validation to ensure that is the case. As soon as you test the code which is saving nulls into that column, the validation errors will point you to the bug.

另一方面,如果你想允许 date_started 中的null,然后重写您的级别方法以允许。

On the other hand, if you want to allow nulls in date_started, then rewrite your levels method to allow for that.

这篇关于如何修复level.rb来处理:承诺的日子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆