Я беру курс, в котором я создаю базовую вики. Я определенно новичок в этом. Мне нужно ограничить пользователей от простого ввода идентификатора вики, который они хотят просмотреть непосредственно в URL-адресе (пример: wikis/5). Единственные люди, которые должны иметь возможность просматривать wiki, должны быть владельцем вики, администратором или сотрудником в этой вики.Как я могу запретить пользователю просматривать страницу, к которой у них нет доступа?
Я успешно ограничил представление индекса, чтобы пользователь, зарегистрированный в системе, только видел свою собственную вики, общедоступную вики или вики, с которыми они сотрудничают.
Я попытался реализовать аналогичный код в своей WikiPolicy, но он не работает, и я не могу найти решение. Код, который у меня есть, просто покажет вики, если пользователь вошел в систему. Я знаю, что моя логика хороша, потому что я могу подставить значение для params [: id] как «5» и работает как ожидалось.
wikis_controller.rb
def show
@wiki = Wiki.find(params[:id])
authorize @wiki
end
wiki_policy.rb
def show?
scope.where(:id => record.id).exists?
current_wiki = Wiki.find(params[:id])
collaborations = Collaboration.where(:user_id => user)
collab_wikis = Wiki.where(id: collaborations.pluck(:wiki_id))
collab_wikis.include?(current_wiki)
end
Вот код, который я использовал в моем wiki_policy.rb вернуть набор вики, что конкретный пользователь авторизован для просмотра. Я считаю, что это работает, потому что он рассматривает все вики, а не зависит от конкретной вики, которую пользователь пытается просмотреть.
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
wikis = []
if user.role?(:admin)
wikis = scope.all # if the user is an admin, show them all the wikis
elsif user.role?(:premium)
collaborations = Collaboration.where(:user_id => user)
collab_wikis = Wiki.where(id: collaborations.pluck(:wiki_id))
all_wikis = scope.all
all_wikis.each do |wiki|
if !wiki.is_private || wiki.user_id == user.id || collab_wikis.include?(wiki)
wikis << wiki # if the user is premium, only show them public wikis, or that private wikis they created, or private wikis they are a collaborator on
end
end
else # this is the lowly standard user
collaborations = Collaboration.where(:user_id => user)
collab_wikis = Wiki.where(id: collaborations.pluck(:wiki_id))
all_wikis = scope.all
wikis = []
all_wikis.each do |wiki|
if !wiki.is_private? || wiki.user_id == user.id || collab_wikis.include?(wiki)
wikis << wiki # only show standard users public wikis and private wikis they are a collaborator on
end
end
end
wikis # return the wikis array we've built up
end
end
Спасибо! Это прекрасно и помогло мне понять, что я пытаюсь сделать лучше. – Tyler