2013-04-02 4 views
1

Я пытаюсь построить метод, в котором я проходил месяц, и затем могу запросить за предыдущий месяц динамически.Учитывая временную метку, как получить 1 месяц назад

total_churn(month) 
    last_month = month - 1 
    companies = Company.where("created_at BETWEEN '#{last_month}' AND '#{month}') 
    return companies.count 
end 

Как передать метод «месяц» в пути, где я могу динамически определить последний месяц, используя рубин на рельсах? Спасибо

+0

так что вы хотите передать строку типа «Январь» или целое число, подобное 1? – jstim

+0

Я могу пройти, что имеет смысл для динамического определения 1 месяц назад, а затем запросить postgres. Спасибо – AnApprentice

+0

Метод не должен полагаться на текущий месяц. Но месяц основан на том, что передается методу. – AnApprentice

ответ

2
My suggestion: accept a date rather than a month. 
total_churn(date) 
    month_previous = date - 1.month 
    companies = Company.where("created_at BETWEEN ? AND ?, '#{month_previous}', '#{date}') 
    return companies.count 
end 

Current month: 
Time.now.month 
Date.today.month 

Time or day one month ago: 
(Time.now - 1.month).month 
(Date.today - 1.month).month 

...also equivalent to: 
Time.now.month - 1 
Date.today.month - 1 

Previous month for any given date: 
@date - 1.month 

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

+0

Это не current_month. Этот вопрос связан с прохождением заданного месяца, в любой желаемый месяц. – AnApprentice

+0

@AnApprentice Затем замените дату, которая требуется для «Date.today» или «Time.now». Он по-прежнему будет работать. – sscirrus

1

У Rails есть полезные помощники времени для создания верхней и нижней границ для вашего запроса. (beginning_of_month и end_of_month в Time class)

Этот метод также правильно экранирован с вопросительными знаками вместо строковой интерполяции, который открыт для атак SQL-инъекций.

def total_churn(month) 
    companies = Company.where('created_at BETWEEN ? and ?',(Time.now - 1.month).beginning_of_month,(Time.now - 1.month).end_of_month) 
    companies.count 
end 

Я бы также сказал, что это будет работать только в течение последнего года. Если вы хотите иметь возможность запрашивать более ранние данные, вы можете либо добавить параметр года, либо просто передать дату, и позволить ему использовать это вместо Time.now.

# with separate year and month params 
def total_churn(month, year) 
    date = DateTime.parse("#{year}/#{month}/01") 
    companies = Company.where('created_at BETWEEN ? and ?',(date - 1.month).beginning_of_month,(date - 1.month).end_of_month) 
    companies.count 
end 

# with a random date input 
def total_churn(date_in_month) 
    companies = Company.where('created_at BETWEEN ? and ?',(date_in_month - 1.month).beginning_of_month,(date_in_month - 1.month).end_of_month) 
    companies.count 
end 
0

Для этого требуется не менее двух параметров, один для месяца и один для года. Это необходимо для определения того, какой месяц вы хотите.

def total_churn(year, month) 
    date = Date.new year, month 
    one_month_ago = date - 1.month 
    ... 

Однако, если у вас уже есть объект даты, вы можете использовать ответ sscirrus. Если дата указана в строке, вы, вероятно, захотите ее сначала проанализировать (например, в вашем комментарии)

def total_churn(date_string) 
    date = Date.parse(date_string) 
    one_month_ago = date - 1.month 
    ... 

>> date_string = '2012-09-01 00:00:00.000000' 
>> total_churn date_string 
Смежные вопросы