default_scope в продолжении

В ActiveRecord есть default_scope метод класса для определения области по умолчанию. Например

class User < ActiveRecord::Base
  default_scope where(:deleted => false)
end

User.all # => SELECT * FROM users WHERE deleted = 0;

Как я могу сделать это в Sequel::Model?

РЕДАКТИРОВАТЬ:

После некоторого поиска в Google я в конечном счете нашел некоторую полезную информацию.

class User < Sequel::Model

  # Define some "scopes" (filters on the dataset)
  dataset_module do
    def existing
      filter(deleted: false)
    end

    def active
      filter(disabled: false)
    end
  end

  # This is the equivalent to a default_scope. Set one of the datasets
  # as the default dataset for this model.
  set_dataset(self.active)
end

Сгенерированный запрос тогда выглядит так:

User.all # => SELECT * FROM `users` WHERE (`deleted` IS FALSE)

Кстати: эквивалент unscoped является unfiltered:

User.unfiltered.all # => SELECT * FROM `users`

Но есть одна проблема. Если вы попытаетесь обновить пользователя, которого вы получили из нефильтрованного набора данных, он попытается обновить пользователя, используя данный набор данных.

User.create(disabled: true, deleted: true)
User.all # => []
u = User.unfiltered.first # => Given user
u.disabled = false
u.save # => UPDATE users SET ... WHERE (disabled IS FALSE AND id = 1)
# => Sequel::NoExistingObject: Attempt to update object did not result in a single row modification

Итак, я вернулся в начале. Любой обходной путь для этого?

1 ответ

Решение

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

Вы также можете справиться с этим путем создания подклассов (у пользователя нет области действия, ActiveUser <пользователь имеет области действия). Тем не менее, я считаю, что явный обзорный подход работает лучше.

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

User.instance_dataset.unfiltered!
Другие вопросы по тегам