Rails: ограничение отображения индекса для отображения только текущих записей

Я запускаю Ruby 2 и Rails 4.

Я создаю приложение, в котором вы можете отслеживать калории и макроэлементы каждого приема пищи, но я хочу, чтобы индекс питания показывал только то, что каждый пользователь вводит на сегодняшний день, а не каждый прием пищи, который они когда-либо вносили.

В настоящее время у меня есть показ только того, что вводится в каждый день, но общая сумма внизу - это все блюда, которые когда-либо были введены, а не только сегодня. Я не могу добавить .created_at.to_date == Date.current в переменную @meals. Он выдает undefined method 'created_at' for 1500:Fixnum

У каждого пользователя есть BMR, который затем вычисляет, сколько калорий и т.д. У них осталось в течение определенного дня.

Мой указатель на моем MealsController:

<% @meals.each do |meal| %>
 
 <% if meal.created_at.to_date == Date.current %>
 
 <% end %>
 
 <% end %>
 
 <% unless current_user.bmr.nil? %>
 
 <% end %>
 <table>
 <thead>
 <tr>
 <th>Name</th>
 <th>Calories</th>
 <th>Protein</th>
 <th>Carbs</th>
 <th>Fats</th>
 </tr>
 </thead>

 <tbody><tr><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></tr><tr>
 <td>Total:</td>
 <td><%= @meals.sum(:calories) %></td>
 <td><%= @meals.sum(:protein) %></td>
 <td><%= @meals.sum(:carbohydrates) %></td>
 <td><%= @meals.sum(:fats) %></td>
 </tr><tr>
 <td>Remaining:</td>
 <td><%= current_user.bmr - @meals.sum(:calories) %></td>
 <td><%= (current_user.bmr*0.4/4).to_i - @meals.sum(:protein) %></td>
 <td><%= (current_user.bmr*0.4/4).to_i - @meals.sum(:carbohydrates) %></td>
 <td><%= (current_user.bmr*0.2/9).to_i - @meals.sum(:fats) %></td>
 </tr></tbody>
</table>

My 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

Заранее спасибо!

2 ответа

Во-первых, я бы взял логику для этого из представления и поместил ее в контроллеры.

Затем вы можете определить две переменные экземпляра.

@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)

Когда вы делаете это, вы полагаетесь на базу данных, делаете сортировку, а не рельсы или рубин, и это приводит к более быстрой работе. Кроме того, сохранение логики вне поля зрения также является большой победой.

Редактировать:

Как упоминал Давиданн в комментарии, вы также можете это сделать, создав область видимости в модели. Ниже приведена реализация этого.

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 вызываться каждый раз, когда оценивается вызов области.


Есть несколько способов сделать это, самым простым добавлением области ActiveRecord, которая только блюда из сегодняшних блюд.

В этом вопросе/ответах есть несколько способов сделать это, выбрать свой любимый.

После этого вы просто измените это:

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

licensed under cc by-sa 3.0 with attribution.