When a user is on Level 1 how can we only show Level 1 checkboxes? If a user is on Level 2 how can we only show Level 2 & Level 1 checkboxes? Etc...
Right now it shows all 5 levels regardless of current level, which can be confusing for a user:
<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
Here's the gist of it: https://gist.github.com/RallyWithGalli/c66dee6dfb9ab5d338c2
Thank you so much for your time! And if you have some spare time here's a similar problem: How to count current level missed_days?
答案 0 :(得分:1)
好的,我想我已经绕过你的代码。你的html来自show
行动吗?除非另有说明,否则我会继续这个假设。所以@habit在set_habit
before_action中设置。因此:
@habit.levels
将返回一系列习惯级别。显然,当创造这种习惯时,它会创建所有五个级别?您没有显示level.rb
模型,但看起来您的关系与habit.rb
代码相反。所以等级属于习惯。看起来你在这里创造了所有五个:
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 %>