Jakie jest wspólne podejście do rekordów zakresu przez te, które użytkownik może „odczytać”?

Używam Ruby on Rails 3.2.2 i chciałbym wiedzieć, jakie jest powszechne podejście, gdy trzeba sprawdzić, czy użytkownik ma odpowiednie uprawnienia do „odczytu” rekordów znajdujących się na „liście” rekordów. Oznacza to, że w tej chwili mam następujące:

class Article < ActiveRecord::Base
  def readable_by_user?(user)
    # Implementation of multiple authorization checks that are not easy to
    # translate into an SQL query (at database level, it executes a bunch of
    # "separate" / "different" SQL queries).

    ... # return 'true' or 'false'
  end
end

Korzystając z powyższego kodu, mogę przeprowadzić sprawdzanie autoryzacji na apojedynczy obiekt artykułu:

@article.readable_by_user?(@current_user)

Jednak, kiedy chciałbym zrobić (zwykle w moim kontrolerzeindex akcja) coś podobnego, pobierając dokładnie 10 obiektów

Article.readable_by_user(@current_user).search(...).paginate(..., :per_page => 10)

Muszę nadal sprawdzać autoryzację każdego obiektu. Więc,co mogę zrobić, aby przeprowadzić kontrolę autoryzacji na tej „liście” rekordów (tablicaArticle obiekty)w „inteligentny” / „wydajny” sposób? To znaczy, na przykład, powinienem załadowaćArticle.all (może zamawiając te przez utworzone dane, ograniczając zapytanie SQL do 10 rekordów ...), a następnie iterując na każdym z tych obiektów, aby przeprowadzić sprawdzanie autoryzacji? czy powinienem zrobić coś innego (może za pomocą jakiegoś triku zapytania SQL, jakiegoś obiektu Ruby on Rails lub czegoś innego)?

AKTUALIZACJA po odpowiedzi @Matzi

Próbowałem odzyskać artykułyczytelny przez użytkownika „ręcznie”, na przykład za pomocąfind_each metoda:

# Note: This method is intended to be used as a "scope" method
#
#   Article.readable_by_user(@current_user).search(...).paginate(..., :per_page => 10)
#
def self.readable_by_user(user, n = 10)
  readable_article_ids = []

  Article.find_each(:batch_size => 1000) do |article|
    readable_article_ids << article.id if article.readable_by_user?(user)

    # Breaks the block when 10 articles have passed the readable authorization 
    # check.
    break if readable_article_ids.size == n
  end

  where("articles.id IN (?)", readable_article_ids)
end

W tym momencie powyższy kod jest najbardziej „wydajnym kompromisem”, o którym mogę myśleć, nawet jeśli ma on jakąś pułapkę: to ”ogranicza„ilość pobranych obiektów z podaną ilością rekordówids (domyślnie 10 rekordów w powyższym przykładzie); praktycznie mówiąc,„naprawdę” nie pobiera wszystkich obiektów czytelnych dla użytkownika od kiedy próbujesz rozszerzyć zakresActiveRecord::Relation „gdzie” / „z którym”readable_by_user używana jest metoda scope (na przykład, gdy chcesz również przeszukiwać artykuły wedługtitle dodając kolejną klauzulę zapytania SQL)ograniczać rekordy do tychwhere("articles.id IN (?)", readable_article_ids) (to znaczy „ogranicza” / „ogranicza” ilość pobranych i czytelnych obiektów do pierwszych 10 i wszystkich innych artykułówczytelny przez użytkownika zostanie zignorowany podczas wyszukiwania wedługtitle). Rozwiązanie problemu, abyreadable_by_user Metodą prawidłowej pracy z dalszymi metodami zakresu może być wykonanienie break blok, aby załadować wszystkoczytelny artykuły, ale nie jest to dobre ze względu na wydajność, gdy istnieje wiele rekordów (być może innym rozwiązaniem może być przechowywanie gdzieś całego artykułuids czytelny dla użytkownika, ale myślę, że nie jest to powszechne / łatwe rozwiązanie problemu).

Więc,jest jakiś sposób, aby osiągnąć to, co chciałbym zrobić w skuteczny i „naprawdę” poprawny sposób (być może, zmieniając w ogóle powyższe podejście)?

questionAnswers(5)

yourAnswerToTheQuestion