Я думаю, что включение site_id в модель не очень хорошая идея, потому что оно может сломаться, если site_id страницы, принадлежащей группе, не совпадает с site_id этой группы.
Это оставило бы только сценарий 1 ...
Если вы хотите иметь возможность создавать site.pages и получать все страницы, принадлежащие этому сайту (также страницы, принадлежащие группе, принадлежащей этому сайту), вы, конечно, можете написать свою собственную функцию:
class Site
def all_pages
Page.find_by_sql(["SELECT p.* FROM pages p, sites s, groups g, projects j WHERE (p.pageable_type='Site' AND p.pageable_id=?) OR (p.pageable_type='Group' AND p.pageable_id=g.id AND g.site_id=?) OR (p.pageable_type='Project' AND p.pageable_id=j.id AND j.site_id=?, self.id, self.id, self.id])
end
end
(Кроме того, я бы назвал столбец pageable_id «parent_id» и pageable_type «parent_type» в этом случае. Мне это кажется более логичным ...)