Я создаю систему стиля библиотеки в Ruby on Rails, и я пытаюсь придумать способ вычислить запоздалые дни, в то время как, исключая выходные, когда одолженный объект возвращается. Прямо сейчас я просто вычисляю "dayslate" как различие между датой истечения срока и датой, объект был на самом деле возвращен, но я хочу исключить выходные, так как объекты могут только быть возвращены в рабочие дни.
Это - мой первый реальный опыт с Ruby и направляющими, таким образом, мои извинения, если я пропускаю что-то очевидное. Спасибо за любую справку можно обеспечить.
Вот код, который я имею для функции "возврата":
def return
@product = Product.find(params[:id])
today = Date.today
dayslate = today - @product.due_date
if @product.due_date >= today
@product.borrower = @product.check_out = @product.due_date = @product.extended_checkout = nil
@product.save!
flash[:notice] = "Okay, it's checked in!"
redirect_to(products_url)
else
@product.borrower = @product.check_out = @product.due_date = @product.extended_checkout = nil
@product.save!
flash[:notice] = "Checked in, but it was #{dayslate} days late!"
redirect_to(products_url)
end
end
Вот фрагмент кода, чтобы найти количество дней недели в диапазоне объектов даты
require 'date'
# Calculate the number of weekdays since 14 days ago
p ( (Date.today - 14)..(Date.today) ).select {|d| (1..5).include?(d.wday) }.size
Вот как я бы использовал его в вашем случае.
class Product
def days_late
weekdays_in_date_range( self.due_date..(Date.today) )
end
protected
def weekdays_in_date_range(range)
# You could modify the select block to also check for holidays
range.select { |d| (1..5).include?(d.wday) }.size
end
end
Если для вас важны праздники (т.е. вы не хотите, чтобы день считался днем недели, если это праздник), вы можете заглянуть на http://rubyforge.org/projects/holidays/. Если совместить петлю @md5sum с проверкой, является ли день недели праздничным, то вы можете быть золотистым.
.Хм... ещё одна вещь, которая может быть полезна с тех пор, как это ваш первый опыт с рельсами - обратите внимание на эту бизнес-логику в контроллере. Ваша модель, вот где она принадлежит.
Вы можете посмотреть страницу this и посмотреть, можете ли вы добавить счетчик в цикл и проверять текущую дату через каждую итерацию.
.нейтрино вполне справедливо относится к перемещению всей логики, которая не задействована в отображении/откате/направлении на модели.
Например
class ProductLoan
def due_date_passed?
days_late > 0
end
def days_late
Date.today - due_date
end
def complete!
self.borrower = self.check_out = self.due_date = self.extended_checkout = nil
save
end
end
class ReturnsController
def create
@product = ProductLoan.find(params[:id])
if @product.due_date_passed?
flash[:notice] = "Okay, it's checked in!"
else
flash[:notice] = "Checked in, but it was #{@product.days_late} days late!"
end
@product.complete!
redirect_to products_url
end
end
Я просто набрал это без тестирования, но что-то в этом направлении могло бы вычислить прошедшие дни, исключая выходные:
class DateOffsetCalculator
DAYS_IN_A_WEEK = 7
DAYS_IN_A_WEEKEND = 2
def initialize(date)
@date = date
end
def compute
days_passed - weekend_days_passed
end
def days_passed
(Date.today - @date).to_i
end
def weekend_days_passed
weekends_passed * DAYS_IN_A_WEEKEND
end
def weekends_passed
rounded_up_week_days / DAYS_IN_A_WEEK
end
def rounded_up_week_days
days_passed + commercial_working_day_correction
end
def commercial_working_day_correction
@date.cwday - 1
end
end