【问题标题】:How to List Tags :committed for Today?如何列出标签:今天提交?
【发布时间】:2015-03-01 18:36:25
【问题描述】:
<% 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 &lt;%= f.collection_check_boxes :committed, Date::DAYNAMES, :downcase, :to_s %&gt; 为用户提供了他在哪天 :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>

非常感谢您的宝贵时间 =]

【问题讨论】:

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


    【解决方案1】:

    由于您将: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),您可以改进您的代码并将类方法转换为具有特定习惯承诺天数的范围。

    【讨论】:

    • 非常感谢!对于控制器代码,我应该把它放在哪个控制器中?
    • 这取决于您要显示标签云的操作。如果它在整个页面中,您可以使用 before_action 和方法在 ApplicationController 中加载该变量。
    • 是的,它用于显示在所有页面上的侧边栏。我是否也应该像处理习惯一样将模型逻辑放入应用程序控制器中?
    • 好答案。我只想补充一点,您不一定需要加载所有用户的习惯来过滤它们。您可以通过将all.select 行替换为where("committed like ?", "%#{today_name}%") 来让sql 处理它
    • 对不起,它是User.first.habits.comitted_for_today,但无论如何如果Habit.comitted_for_today 为空,那么其他查询也将为空。我刚刚看到您正在存储小写的日期名称。我正在更新我的答案,你告诉我你是否能够在控制台中从数据库中检索结果。
    猜你喜欢
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    相关资源
    最近更新 更多