Как заказать Rails Collection с областью применения? - PullRequest
2 голосов
/ 29 октября 2019

Учитывая область, которая определяет, является ли модель активной или нет ..

def active?
    return false unless published_at && expires_at && id

    DateTime.now.between? published_at, expires_at
  end

Как использовать эту область с другими областями для сортировки коллекции?

Это делаетне похоже на работу.

@posts = current_user.posts
        .includes(:orgs)
        .order(:active?)
        .order(created_at: :desc)

1 Ответ

4 голосов
/ 29 октября 2019

Ваш код не работает, потому что вы возвращаете boolean в обоих случаях. И boolean не может быть цепочкой.

Вместо этого вам нужно вернуть ActiveRecord_Relation, которая может быть цепочкой. Так что, возможно, что-то более похожее на:

def active?
  return none unless published_at && expires_at && id
  where("published_at <= ? AND expires_at >= ?", DateTime.now, DateTime.now)
end

TBH, я не уверен, что там есть бит published_at && expires_at && id (потому что published_at, expires_at и id - это все методы экземпляра иВы сказали, что хотите область, а область находится в контексте класса). Так что, возможно, это больше похоже на:

def active?
  where("published_at <= ? AND expires_at >= ?", DateTime.now, DateTime.now)
end

И вы сказали, что хотите, чтобы это было сферой. Итак, я думаю,

scope :active?, -> { where("published_at <= ? AND expires_at >= ?", DateTime.now, DateTime.now) }

Область действия - это на самом деле просто метод класса. Таким образом, это также может быть как:

class << self

  def active?
    where("published_at <= ? AND expires_at >= ?", DateTime.now, DateTime.now)
  end

end

... или:

def self.active?
  where("published_at <= ? AND expires_at >= ?", DateTime.now, DateTime.now)
end

... в зависимости от того, что плавает на вашей лодке.

Теперь, какЯ сказал, что это вернет ActiveRecord_Relation, но ничего не делает с сортировкой. Я думаю, это выглядело бы так:

@posts =  current_user.
            posts.
            includes(:orgs).
            active?.
            order(created_at: :desc)

Лично я думаю, что я бы разбил эту область, чтобы это было больше похоже на:

class << self

  def active?
    published?.not_expired?
  end

  def published?
    where("published_at <= ?", DateTime.now)
  end

  def not_expired?
    where.not("expires_at <= ?", DateTime.now)
  end

end

, потому что где-то еще вы можете захотеть использовать published? и not_expired?.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...