Rails: как найти всех пользователей старше n минут назад, где n хранится в объединенной группе - PullRequest
0 голосов
/ 31 октября 2011

У меня есть User модель и Group модель. User принадлежит_ Group. Group имеет атрибут check_minutes.

Я хочу создать две области в модели User: old и fresh. Старые пользователи - это пользователи с created_at старше user.group.check_minutes.ago. А новые пользователи - это пользователи с created_at новее, чем user.group.check_minutes.ago.

Я написал прицелы:

  scope :old,   joins(:group).where("`users`.`created_at` <=
        DATE_SUB(NOW(), INTERVAL `groups`.`check_minutes` MINUTE)")
  scope :fresh, joins(:group).where("`users`.`created_at` >
        DATE_SUB(NOW(), INTERVAL `groups`.`check_minutes` MINUTE)")

И характеристики:

  describe "scopes" do
    let(:group) {Group.make :check_minutes => 20}
    let(:old_user) {User.make :group => group, :created_at => 30.minutes.ago}
    let(:new_user) {User.make :group => group, :created_at => 10.minutes.ago}

    context "#fresh" do
      it "should scope all new users" do
        User.fresh.should eq([ new_user ])
      end
    end
    context "#old" do
      it "should scope all old users" do
        User.old.should eq([ old_user ])
      end
    end
  end

Спецификации не работают на fresh (для old это нормально):

  expected  [#<User id: 7967, ... >]
        got []

Что не так ?! Как заставить мои прицелы \ спецификации работать хорошо?

Было бы замечательно, если бы вы знали лучший способ организации областей действия!

1 Ответ

2 голосов
/ 31 октября 2011

Ваши возможности в порядке.

Проблема, с которой вы столкнулись, заключается в том, что Rails хранит значения времени UTC в базе данных независимо от настроенного часового пояса базы данных и преобразует их в ваш часовой пояс (Rails) при выполнении ORM.

... Что означает, что ваши области действия почти ОК - вам просто нужно вставить текущее время Rails в запрос.

scope :old, lambda {  joins(:group).where(["`users`.`created_at` <=
    DATE_SUB(?, INTERVAL `groups`.`check_minutes` MINUTE)", Time.zone.now]) }
scope :fresh, lambda { joins(:group).where(["`users`.`created_at` >
    DATE_SUB(?, INTERVAL `groups`.`check_minutes` MINUTE)", Time.zone.now]) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...