如何只显示以前和当前级别的复选框?

How to only show previous & current level checkboxes?

当用户处于 1 级时,我们如何才能只显示 1 级复选框?如果用户处于 2 级,我们如何才能只显示 2 级和 1 级复选框?等等...

现在它显示了所有 5 个级别,与当前级别无关,这可能会让用户感到困惑:

<label id="<%= @habit.id %>" class="habit-id"> Missed: </label>
  <% @habit.levels.each_with_index do |level, index| %>
    <p>
      <label id="<%= level.id %>" class="level-id"> Level <%= index + 1 %>: </label>
      <%= check_box_tag nil, true, level.missed_days > 0, {class: "habit-check"} %>
      <%= check_box_tag nil, true, level.missed_days > 1, {class: "habit-check"} %>
      <%= check_box_tag nil, true, level.missed_days > 2, {class: "habit-check"} %>
    </p>
  <% end %>

habit.rb

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

habits_controller

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 = current_user.habits.order("date_started DESC")
    end
  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_with_current_level
        track_activity @habit
        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, 
      :trigger,
      :tag_list,
      :current_level,
      :missed_days,
      :target, 
      :reward,
      :comment,
      :private,
      :order,
      :date_started,
      :missed_one, 
      :committed => [],
      levels_attributes: [
      :missed_days])
  end
end

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

非常感谢抽出宝贵时间!如果你有空闲时间,这里有一个类似的问题:

好的,我想我正在仔细研究您的代码。您的 html 是来自 show 行动吗?除非您另有说明,否则我将继续进行该假设。所以@habit 在 set_habit before_action 中设置。因此:

@habit.levels 

将 return 一系列习惯级别。显然,当养成这种习惯时,它会创造所有五个级别?您没有显示 level.rb 模型,但看起来您的关系与 habit.rb 代码相反。所以级别belongs_to习惯了。看起来你在这里创建了所有五个:

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

因此,要么只在达到关卡时创建关卡,要么在视图的循环代码中跳过未达到关卡的关卡。

<label id="<%= @habit.id %>" class="habit-id"> Missed: </label>
<% @habit.levels.each_with_index do |level, index| %>
  <% if @habit.current_level >= (index + 1) %>
    <p>
      <label id="<%= level.id %>" class="level-id"> Level <%= index + 1 %>: </label>
      <%= check_box_tag nil, true, level.missed_days > 0, {class: "habit-check"} %>
      <%= check_box_tag nil, true, level.missed_days > 1, {class: "habit-check"} %>
      <%= check_box_tag nil, true, level.missed_days > 2, {class: "habit-check"} %>
   </p>
  <% end %>
<% end %>