如何列出标签 :committed for Today?
How to List Tags :committed for Today?
<% tag_cloud Habit.tag_counts, %w{m} do |tag, css_class| %>
<%= link_to tag.name, taghabits_path(tag.name), class: css_class %>
<% end %>
以上代码列出了所有习惯标签。但是我们怎样才能让它只列出今天有习惯:committed
的标签呢?
在习惯 _form <%= f.collection_check_boxes :committed, Date::DAYNAMES, :downcase, :to_s %>
中,用户可以选择在哪几天 :committed
养成自己的习惯。
[ ] Sunday [ ] Monday [ ] Tuesday [ ] Wednesday [ ] Thursday [ ] Friday [ ] Saturday
习惯模型
class Habit < ActiveRecord::Base
belongs_to :user
before_save :set_level
acts_as_taggable
serialize :committed, Array
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
protected
def set_level
self.level = levels
end
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
因为这段代码是在侧边栏中呈现的,我认为我们必须向 ApplicationController 添加控制器逻辑,就像我对 set_top_3_goals
所做的那样。
应用程序控制器
class ApplicationController < ActionController::Base
before_action :set_top_3_goals
protect_from_forgery with: :exception
include SessionsHelper
def set_top_3_goals
@top_3_goals = current_user.goals.unaccomplished.top_3 if logged_in?
end
private
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
end
views/layouts/_sidebar.html.erb
<div id="sidebarsectiontop" class="panel panel-default">
<div id="sidebarheadingtop" class="panel-heading"><h5><b>Today</b></h5></div>
<%= render 'habits/today' %>
</div>
<div id="sidebarsection" class="panel panel-default">
<div id="sidebarheading" class="panel-heading"><h5><b>Upcoming</b></h5></div>
<%= render 'goals/upcoming' %>
</div>
非常感谢您的宝贵时间=]
由于您将 :committed
属性定义为 serialize
,您无法直接查询数据库以获取特定日期(今天)内的习惯,因此您需要将所有习惯来自数据库,然后像这样用所需的承诺日期过滤它们:
class Habit < ActiveRecord::Base
def self.comitted_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
end
然后在您的 ApplicationController 中,因为您希望侧边栏跨站点显示:
class ApplicationController < ActionController::Base
before_action :load_todays_habits
private
def load_todays_habits
@user_tags = current_user.habits.comitted_for_today.tag_counts
@all_tags = Habit.comitted_for_today.tag_counts
end
end
最后,您的视图可以使用用户标签的第一个列表或所有标签的最后一个列表,两者都是今天提交的:
<% tag_cloud @user_tags, %w{m} do |tag, css_class| %>
<%= link_to tag.name, taghabits_path(tag.name), class: css_class %>
<% end %>
<% tag_cloud @all_tags, %w{m} do |tag, css_class| %>
<%= link_to tag.name, taghabits_path(tag.name), class: css_class %>
<% end %>
Extra ball:如果您使用 PostgreSQL 的本机数组支持,您可以改进代码并将 class 方法变成具有特定习惯承诺日的范围( see here for a good guide)。
<% tag_cloud Habit.tag_counts, %w{m} do |tag, css_class| %>
<%= link_to tag.name, taghabits_path(tag.name), class: css_class %>
<% end %>
以上代码列出了所有习惯标签。但是我们怎样才能让它只列出今天有习惯:committed
的标签呢?
在习惯 _form <%= f.collection_check_boxes :committed, Date::DAYNAMES, :downcase, :to_s %>
中,用户可以选择在哪几天 :committed
养成自己的习惯。
[ ] Sunday [ ] Monday [ ] Tuesday [ ] Wednesday [ ] Thursday [ ] Friday [ ] Saturday
习惯模型
class Habit < ActiveRecord::Base
belongs_to :user
before_save :set_level
acts_as_taggable
serialize :committed, Array
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
protected
def set_level
self.level = levels
end
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
因为这段代码是在侧边栏中呈现的,我认为我们必须向 ApplicationController 添加控制器逻辑,就像我对 set_top_3_goals
所做的那样。
应用程序控制器
class ApplicationController < ActionController::Base
before_action :set_top_3_goals
protect_from_forgery with: :exception
include SessionsHelper
def set_top_3_goals
@top_3_goals = current_user.goals.unaccomplished.top_3 if logged_in?
end
private
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
end
views/layouts/_sidebar.html.erb
<div id="sidebarsectiontop" class="panel panel-default">
<div id="sidebarheadingtop" class="panel-heading"><h5><b>Today</b></h5></div>
<%= render 'habits/today' %>
</div>
<div id="sidebarsection" class="panel panel-default">
<div id="sidebarheading" class="panel-heading"><h5><b>Upcoming</b></h5></div>
<%= render 'goals/upcoming' %>
</div>
非常感谢您的宝贵时间=]
由于您将 :committed
属性定义为 serialize
,您无法直接查询数据库以获取特定日期(今天)内的习惯,因此您需要将所有习惯来自数据库,然后像这样用所需的承诺日期过滤它们:
class Habit < ActiveRecord::Base
def self.comitted_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
end
然后在您的 ApplicationController 中,因为您希望侧边栏跨站点显示:
class ApplicationController < ActionController::Base
before_action :load_todays_habits
private
def load_todays_habits
@user_tags = current_user.habits.comitted_for_today.tag_counts
@all_tags = Habit.comitted_for_today.tag_counts
end
end
最后,您的视图可以使用用户标签的第一个列表或所有标签的最后一个列表,两者都是今天提交的:
<% tag_cloud @user_tags, %w{m} do |tag, css_class| %>
<%= link_to tag.name, taghabits_path(tag.name), class: css_class %>
<% end %>
<% tag_cloud @all_tags, %w{m} do |tag, css_class| %>
<%= link_to tag.name, taghabits_path(tag.name), class: css_class %>
<% end %>
Extra ball:如果您使用 PostgreSQL 的本机数组支持,您可以改进代码并将 class 方法变成具有特定习惯承诺日的范围( see here for a good guide)。