我正在运行Ruby 2和Rails 4。
我正在创建一个应用程序,您可以在其中跟踪每餐的卡路里和常量营养素,但我希望膳食指数仅显示每个用户今天输入的内容,而不是他们曾经输入的每餐。
我目前只显示每天输入的内容,但底部的总数是所有已输入的餐点,而不仅仅是今天的总数。我无法将.created_at.to_date == Date.current
添加到@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>
我的MealsController:
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
提前谢谢!
答案 0 :(得分: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在评论中提到的,您还可以通过在模型中创建范围来实现此目的。以下是该实现。
meal.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。
答案 1 :(得分:2)
有几种方法可以做到这一点,最简单的方法是添加an ActiveRecord scope,这只是今天的菜肴。
This SO question/answers has several methods of doing it,选择你最喜欢的。
之后,您只需更改此内容:
def index
@meals = current_user.meals.today if user_signed_in?
end