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

Я использую Ruby on Rails 3.2.2, и я хотел бы знать, что является общим подходом, когда он должен быть проверен, если у пользователя есть надлежащие полномочия для "чтения" записи, представленные в «списке»; записей. То есть на данный момент у меня есть следующее:

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

Используя приведенный выше код, я могу выполнить проверку авторизации наsingle объект статьи:

@article.readable_by_user?(@current_user)

Тем не менее, когда я хотел бы сделать (обычно, в моем контроллереindex действие) что-то вроде следующего, получая ровно 10 объектов

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

Я все еще должен выполнить проверки авторизации для каждого объекта. Так,what I can make to perform authorization checks on that "list" of records (массивArticle объекты)in a "smart" / "performant" way? То есть, например, я должен загрузитьArticle.all (может быть, упорядочить их по созданным данным, ограничив запрос SQL 10 записями, ...), а затем выполнить итерацию для каждого из этих объектов, чтобы выполнить проверки авторизации? или я должен сделать что-то другое (может быть, с помощью какого-то трюка с SQL-запросом, какого-либо средства Ruby on Rails или чего-то еще)?

UPDATED after @Matzi answer

Я пытался получить статьиreadable пользователем "вручную", например, с помощьюfind_each метод:

# 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

В настоящее время приведенный выше код является наиболее «компромиссным вариантом». о чем я могу подумать, даже если в этом есть какая-то ошибка: это & quot;restricts& Quot; количество найденных объектов для заданного количества записей с заданнымids (10 записей по умолчанию в приведенном выше примере); практически говоря,it "really" doesn't retrieve all objects readable by an user с тех пор, когда вы пытаетесь расширить рамки связанныхActiveRecord::Relation & Quot; где & Quot; / "с помощью которого"readable_by_user используется метод области видимости (например, когда вы также будете искать статьи поtitle добавив еще одно предложение SQL-запроса),restrict записи к темwhere("articles.id IN (?)", readable_article_ids) (то есть «ограничивает» / «ограничивает» количество извлекаемых и читаемых объектов первыми 10 и всеми остальными статьямиreadable пользователем будет игнорироваться при поискеtitle). Решение проблемы для того, чтобы сделатьreadable_by_user метод для правильной работы с другими методами области может быть сделатьnot break блок, так что загрузить всеreadable статьи, но это не годится по причинам производительности, когда записей много (возможно, другое решение - хранить где-то всю статьюidМожет быть прочитано пользователем, но я думаю, что это не общее / простое решение проблемы).

Так,there is some way to accomplish what I would like to make in a performant and "really" correct way (maybe, by changing the above approach at all)?

Ответы на вопрос(5)

Ваш ответ на вопрос