验证失败:开始日期不能为空(但它不是空白!)

时间:2015-08-11 16:23:31

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

在用户注册期间,他可以在来到用户之前提交“习惯”,然后将其保存并删除到会话中,但在登录后,他会收到以下错误消息:

ActiveRecord::RecordInvalid in UsersController#create
Validation failed: Date started can't be blank
for line: self.save!

但正如您所看到的那样,默认情况下,在注册过程中将日期设置为今天:

enter image description here

habit.rb

class Habit < ActiveRecord::Base
    belongs_to :user
    has_many :levels, -> { order(:id) }
    validates :date_started, :action, presence: true
    before_save :current_level
    attr_accessor :missed_one, :missed_two, :missed_three

    # This gets used when user submits as a user (works correctly)
    def save_with_current_level
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.save
    end

    # This gets used when nil user submits (doesn't work)
    def create_with_current_level
      self.save!
      5.times {self.levels.create!} 
    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
          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 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

habits_controller

  def habit_signup
    @habit = Habit.new
  end

  def create
    if current_user == nil
      session[:habit_date_started] = habit_params[:date_started]
      session[:habit_committed] = habit_params[:committed => []]
      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 valuation_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 secretly created. Remember, 3 strikes and your level restarts. Good luck!'
      elsif
        @habit.save_with_current_level
        track_activity @habit
        redirect_to @habit, notice: 'Habit was successfully created. Remember, 3 strikes and your level restarts. Good luck!'
      else
        flash.now[:danger] = 'Required Fields: "Committed to", "Started", and "Enter Habit"'
        render 'new'
      end
    end
  end

  def habit_params
    params.require(:habit).permit(
      :user_id, 
      :trigger,
      :tag_list,
      :current_level,
      :conceal,
      :missed_days,
      :target, 
      :reward,
      :comment,
      :commentable,
      :like,
      :likeable,
      :action,
      :order,
      :date_started,
      :missed_one,
      :completed,
      :completed_at,
      :notes_text,
      :notes_date, 
      :notable, 
      :note, 
      :committed => [],
      levels_attributes: [
      :missed_days,
      :days_lost], notes_attributes: [:notable, :note, :notes_text, :notes_date, :_destroy])
  end

users_controller

  def create
    @user = User.new(user_params)
    if @user.save
      # Goals
      name = session.delete(:goal_name)
      deadline = session.delete(:goal_deadline)
      # Values
      vname = session.delete(:valuation_name)
      vimage = session.delete(:valuation_image)
      # Habits
      date_started = session.delete(:habit_date_started)
      committed = session.delete(:habit_committed)
      trigger = session.delete(:habit_trigger)
      action = session.delete(:habit_action)
      target = session.delete(:habit_target)
      reward = session.delete(:habit_reward)
      missed_days = session.delete(:habit_missed_days)
      # Stats
      scategories = session.delete(:stat_categories)
      saction = session.delete(:stat_action)
      smetric = session.delete(:stat_metric)
      sresults_attributes = session.delete(:stat_results_attributes)
      @user.habits.create(date_started: date_started, committed: committed, trigger: trigger, action: action, target: target, reward: reward, missed_days: missed_days).create_with_current_level
      @user.goals.create(name: name, deadline: deadline)
      @user.valuations.create(name: vname, image: vimage)
      @user.stats.create(categories: scategories, action: saction, metric: smetric, results_attributes: sresults_attributes)
      @user.send_activation_email
      redirect_to root_url
    else
      render 'new'
    end
  end

  private

  def user_params
    if params[:conceal] = true
      params.require(:user).permit(:name, :email, :tag_list, :password, :conceal, :password_confirmation, valuations_attributes: [:name, :tag_list, :conceal], activities_attributes: [:conceal, :action, :trackable_id, :trackable_type])
    else
      params[:user][:valuations][:conceal] = false
      params.require(:user).permit(:name, :image, :tag_list, :email, :password, :password_confirmation, valuations_attributes: [:name, :tag_list], activities_attributes: [:action, :trackable_id, :trackable_type])
    end
  end

错误来自here on SO给出的答案。

更新

habit / habit_signup.html.erb (是正在呈现的表单)

<%= simple_form_for(@habit) do |f| %> <%= f.error_notification %>
  <div class="add-form-padding">
    <form>
      <div class="committed">
        <span class="label label-primary" data-toggle="tooltip" data-placement="left" title="Check off the days you plan on doing your habit.">Committed to:</span>
        <%= f.collection_check_boxes :committed, Date::ABBR_DAYNAMES, :downcase, :to_s %>
      </div>
      <div class="committed">
        <span class="label label-primary">Started:</span>
        <%= f.date_select :date_started, :order => [:month, :day, :year], class: 'date-select' %>
      </div>
      <br>
      <br>
      <div class="center-buttons-habits">
        <div class="form-inline">
          <a data-toggle="tooltip" data-placement="top" title="AFTER I... wake up, brush my teeth, leave the house, turn on my computer, take a shower, etc.">
            <label>After I</label> 
            <%= f.text_field :trigger, class: 'underlining', placeholder: 'Enter Trigger', id: 'centered' %>, &nbsp;
          </a>
          <a data-toggle="tooltip" data-placement="top" title="I WILL... read, write, run, study, pushup, exercise, stretch, meditate, walk, etc.">
            <label>I will</label> 
            <%= f.text_field :action, class: 'underlining', id: "three-gold-standard", placeholder: 'Enter Habit' %>
          </a>
          <br>
          <a data-toggle="tooltip" data-placement="bottom" title="UNTIL... 2 miles, a chapter, 500 words, 20 min, 15 reps, 10,000 steps, etc.">
            <label>until</label>
            <%= f.text_field :target, class: 'underlining', placeholder: 'Enter Target', id: 'centered' %> &nbsp;
          </a>
          <a data-toggle="tooltip" data-placement="bottom" title="SO I MAY... eat dessert, watch TV, drink coffee, go on a cruise, feel more energized & focused, etc.">
          <label>so I may</label>
          <%= f.text_field :reward, class: 'underlining', placeholder: 'Enter Reward', id: 'centered' %> .
          </a>
        </div>
        <br>
        <br>
        <div class="center-buttons">
            <%= button_tag(type: 'submit', class: "btn")  do %>
             <span class="glyphicon glyphicon-plus"></span> Submit
            <% end %>
        </div>
        <br>
        <br>
     <div class="float-right-box">
      <%= link_to goal_signup_path, class: "btn" do %>
        <span class="glyphicon glyphicon-chevron-left"></span> Back
      <% end %>
      <%= link_to valuation_signup_path, class: "btn" do %>
        Skip <span class="glyphicon glyphicon-chevron-right"></span>
      <% end %>
    </div>
    </form>
  </div>
<% end %>

<% content_for :jumbotron do %>
  <div class="jumbtron"
    <div class="jumbtron">
      <div class="container">
        <h1><b>Enter a Habit</b></h1>
          <p>Next, enter an actionable, specific, tiny,</br>
          good habit that will <u>help you</u> achieve your goal.</br>
          Gray underlined text is optional.</p>
      </div>
    </div>
  </div>
<% end %>

将习惯提交为nil用户:

Started POST "/habits" for 127.0.0.1 at 2015-08-11 13:15:40 -0400
Processing by HabitsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"EDxn180pxfaqNCBNtzxJd3Y0XHO5m9eURhj9WOf25Re64ed0f99HlIXIgHfNpyJIi1KD92SQ/QggcTCf7pZPHw==", "habit"=>{"committed"=>["sun", "mon", "tue", "wed", "thu", "fri", "sat", ""], "date_started(2i)"=>"8", "date_started(3i)"=>"11", "date_started(1i)"=>"2015", "trigger"=>"test", "action"=>"test", "target"=>"test", "reward"=>"test"}, "button"=>""}
Redirected to http://0.0.0.0:3000/valuation_signup
Completed 302 Found in 11ms (ActiveRecord: 0.0ms)

1 个答案:

答案 0 :(得分:1)

问题在于如何通过日期的参数。将它保存到会话变量时,请执行以下操作:

session[:habit_date_started] = [params["habit"]["date_started(3i)"], params["habit"]["date_started(2i)"], params["habit"]["date_started(1i)"]].join('/')
# => "11/8/2015"

然后在@user.habits.create期间将其保存到数据库时请记住,您可能需要根据数据库类型I.E。将其解析为Date或DateTime值。

@user.habits.create(date_started: Date.parse(date_started), ...
# => Tue, 11 Aug 2015 

@user.habits.create(date_started: DateTime.parse(date_started), ...
# => Tue, 11 Aug 2015 00:00:00 +0000