0

我正在运行 Ruby 2 和 Rails 4。

我正在创建一个应用程序,您可以在其中跟踪每餐的卡路里和常量营养素,但我希望膳食指数仅显示每个用户今天输入的内容,而不是他们曾经输入的每餐。

我目前只显示每天输入的内容,但底部的总数是曾经输入过的所有餐点,而不仅仅是今天的总数。我无法将.created_at.to_date == Date.currenton 添加到@meals变量中。它抛出一个undefined method 'created_at' for 1500:Fixnum

每个用户都有一个 BMR,然后计算他们在特定一天剩余的卡路里等。

MealsController 上的索引视图:

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Calories</th>
      <th>Protein</th>
      <th>Carbs</th>
      <th>Fats</th>
    </tr>
  </thead>

  <tbody>
    <% @meals.each do |meal| %>
      <tr class= "value">
        <% if meal.created_at.to_date == Date.current %>
          <td><%= link_to meal.name, edit_meal_path(meal) %></td>
          <td><%= meal.calories %></td>
          <td><%= meal.protein %></td>
          <td><%= meal.carbohydrates %></td>
          <td><%= meal.fats %></td>
        <% end %>
      </tr>
    <% end %>
      <tr>
        <td class="meal-total">Total:</td>
        <td class="meal-total"><%= @meals.sum(:calories) %></td>
        <td class="meal-total"><%= @meals.sum(:protein) %></td>
        <td class="meal-total"><%= @meals.sum(:carbohydrates) %></td>
        <td class="meal-total"><%= @meals.sum(:fats) %></td>
      </tr>
      <% unless current_user.bmr.nil? %>
        <tr class="remaining">
          <td class="meal-remaining">Remaining:</td>
          <td class="meal-remaining"><%= current_user.bmr - @meals.sum(:calories) %></td>
          <td class="meal-remaining"><%= (current_user.bmr*0.4/4).to_i - @meals.sum(:protein) %></td>
          <td class="meal-remaining"><%= (current_user.bmr*0.4/4).to_i - @meals.sum(:carbohydrates) %></td>
          <td class="meal-remaining"><%= (current_user.bmr*0.2/9).to_i - @meals.sum(:fats) %></td>
        </tr>
      <% end %>
  </tbody>
</table>

我的膳食控制器:

class MealsController < ApplicationController
  before_action :set_meal, only: [:edit, :update, :destroy]
  before_action :authenticate_user!, except: :index

  def index
    @meals = current_user.meals if user_signed_in?
  end
  .
  .
  .
  .
end

先感谢您!

4

2 回答 2

3

首先,我会将其逻辑从视图中取出,并将其放入控制器中。

然后,您可以定义两个实例变量。

@todays_meals = current_user.meals.where("created_at > ? AND created_at < ?", Time.now.beginning_of_day, Time.now.end_of_day)
@previous_meals = current_user.meals.where("created_at < ?", Time.now.beginning_of_day)

当你这样做时,你依赖于数据库进行排序而不是 rails 或 ruby​​,这会导致更快的操作。此外,将逻辑排除在视野之外也是一大胜利。

编辑:

正如 Davidann 在评论中提到的,您还可以通过在模型中创建范围来完成此操作。下面是一个实现。

膳食.rb

scope :today, lambda {
  where('created_at > ?', Time.now.beginning_of_day)
  .where('created_at < ?', Time.now.end_of_day) 
}

@user.meals.today

如果您发现自己多次执行我的第一个实现,请创建一个类似上面的范围。如果不是,那么您是否希望这个范围在您的模型内或控制器内是由您决定的。另外,请注意,范围内的lamdba需要允许 Time.now 在每次评估范围调用时被调用。

于 2013-10-16T14:41:02.347 回答
2

有几种方法可以做到这一点,最简单的方法是添加一个 ActiveRecord 范围,它只提供今天的饭菜。

这个 SO question/answers 有几种方法,选择你最喜欢的。

之后,您只需更改以下内容:

def index
  @meals = current_user.meals.today if user_signed_in?
end
于 2013-10-16T14:40:00.903 回答