如何列出标签:今天承诺?

时间:2015-03-01 18:36:26

标签: ruby-on-rails ruby tags sidebar acts-as-taggable-on

<% 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

视图/布局/ _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>

非常感谢你的时间=]

1 个答案:

答案 0 :(得分:2)

由于您已将: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 %>

额外的球:如果您使用PostgreSQL(see here for a good guide)的本机阵列支持,您可以改进代码并将类方法转换为具有特定习惯承诺日的范围。