How to save session with “save_with_current_level”

2019-09-18 01:33发布

问题:

Once a nil user submits a habit it should be saved to the session and then to the user once he creates an account, as @blnc was able to help me get it to work for goals.

It doesn't work for habit's though and I think it's because I'm suppose to add save_with_current_level to it as I do when it is saved by an actual user in the habit's_controller.

  def create
    if current_user == nil
      # If there is no user, store the goal values to the session.
      session[:habit_committed] = habit_params[:committed => []]
      session[:habit_date_started] = habit_params[:date_started]
      session[:habit_trigger] = habit_params[:trigger]
      session[:habit_action] = habit_params[:action]
      session[:habit_target] = habit_params[:target]
      session[:habit_reward] = habit_params[:reward]
      session[:habit_order] = habit_params[:order]
      session[:habit_missed_days] = habit_params[:missed_days]
      redirect_to signup_url
    else
      @habit = current_user.habits.build(habit_params)
      if @habit.conceal == true
        @habit.save_with_current_level
        redirect_to @habit, notice: 'Habit was successfully created. Remember, if you miss a "committed" day give yourself a strike.
  3 strikes and your current level restarts. Good luck!'
      elsif
        @habit.save_with_current_level
        track_activity @habit
        redirect_to @habit, notice: 'Habit was successfully published. Remember, if you miss a "committed" day give yourself a strike.
  3 strikes and your current level restarts. Good luck!'
      else
        flash.now[:danger] = 'Required Fields: "Committed to", "Started", and "Enter Habit"'
        render 'new'
      end
    end
  end

users_controller

  def create
    @user = User.new(user_params)
    if @user.save
      # Grab the session variable at the same time deleting it
      name = session.delete(:goal_name)
      deadline = session.delete(:goal_deadline)
      vname = session.delete(:valuation_name)
      vimage = session.delete(:valuation_image)
      committed = session.delete(:habit_committed)
      date_started = session.delete(:habit_date_started)
      trigger = session.delete(:habit_trigger)
      action = session.delete(:habit_action)
      target = session.delete(:habit_target)
      reward = session.delete(:habit_reward)
      order = session.delete(:habit_order)
      missed_days = session.delete(:habit_missed_days)
      # I believe it's because the line below does not save_with_current_level
      @user.habits.create(committed: committed, date_started: date_started, trigger: trigger, action: action, target: target, reward: reward, order: order, missed_days: missed_days).save_with_current_level
      @user.goals.create(name: name, deadline: deadline)
      @user.valuations.create(name: vname, image: vimage)
      @user.send_activation_email
      redirect_to root_url
    else
      render 'new'
    end
  end

habit.rb

class Habit < ActiveRecord::Base
    belongs_to :user
    has_many :levels, -> { order(:id) }
    before_save :current_level

    def save_with_current_level
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.save
    end

    def current_habit_level 
        self.levels.order("id asc").limit(self.current_level).last 
    end

attr_accessor :missed_one, :missed_two, :missed_three

    def completed=(boolean)
      self.completed_at = boolean ? Time.current : nil
    end

    def completed
      completed_at && completed_at >= Time.current.beginning_of_day
    end

    def self.committed_for_today
    today_name = Date::ABBR_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
          def committed_wdays
            committed.map do |day|    
              Date::ABBR_DAYNAMES.index(day.titleize)
            end
          end

          def n_days
            ((date_started.to_date)..Date.yesterday).count do |date| 
              committed_wdays.include? date.wday
            end - self.real_missed_days
          end     

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

 def real_missed_days
     value = 0
     levels.each do |level|
         value += level.missed_days + level.days_lost
     end
     value
  end

  def calculate_days_lost
      def n_days
        ((date_started.to_date)..Date.yesterday).count do |date| 
          committed_wdays.include? date.wday
        end - self.real_missed_days
      end     

   case n_days    
      when 0..9
        n_days
      when 10..24
        n_days-10
      when 25..44
        n_days-25
      when 45..69
        n_days-45
      when 70..99
        n_days-70
      else
        n_days-100
    end
  end

    def days_left_in_current_level
        def n_days
            ((date_started.to_date)..Date.yesterday).count do |date|
                committed_wdays.include? date.wday
            end - self.real_missed_days
        end

        case n_days
          when 0..9
            10-n_days
          when 10..24
            25-n_days
          when 25..44
            45-n_days
          when 45..69
            70-n_days
          when 70..99
            100-n_days
          else
            0 # No end
        end
    end
end

回答1:

I'm not exactly sure what your problem is, but I think it's again that you're not saving you're levels. Also you have to save your habits first, otherwise ther is no id to assign your levels to

def save_with_current_level
    self.save!
    5.times {self.levels.create!} 
end