Существуют различные проблемы в дизайне вашего приложения.
Первый - это взаимосвязь Вопросов:
class Question < ApplicationRecord
belongs_to :user
belongs_to :paper
belongs_to :project
end
Я понимаю, что вы пытаетесь сделать здесь: вопрос может относиться к различным моделям: пользователь, бумагапроект.Хотя есть проблема: вопрос может относиться только к одной из этих моделей (было бы странно, если бы вопрос относился к разным объектам одновременно).Затем при создании нового вопроса, касающегося пользователя, внешние ключи для бумаги (paper_id
) и проекта (project_id
) будут пустыми.
Это не очень хороший дизайн.Способ сделать это - сделать модель «Вопрос» полиморфной моделью.
В случае, если Вопрос относится только к бумагам, как вы упомянули выше, тогда почему Вопрос является дочерним для других моделей, кроме Бумаги?
Вторая проблема : вы пытаетесь получитьВопросы с двумя внешними ключами:
@replies = Question.where("project_id = ? AND paper_id = ?", params[:project_id], params[:paper_id])
Как я уже описывал ранее в задаче 1, ваша модель Вопроса может иметь 3 внешних ключа (для 3 моделей, к которым она принадлежит), но вопросне может относиться к более чем одной модели одновременно.
Таким образом, когда вы пытаетесь получить вопросы с этими двумя внешними ключами одновременно, вы можете не получить ответа на свой запрос.
Третья проблема : используйте поверхностное вложение, ваши маршруты слишком глубокие:
http://0.0.0.0:3000/projects/3/papers/2/questions/1/replies
Вам не нужно три уровня вложенности здесь,Вы, кажется, новичок, поэтому он может показаться вам не интуитивным, но проверьте мое предложение ниже
предложение :
Если я правильно прочитал ваш макет вопроса, вопросы относятся только к документам,Тогда, если вы хотите получить все вопросы, связанные с этой самой статьей, лучше создать новый метод get replies
в этой самой модели, а не в модели вопроса.
Сделать его участником, а не коллекцией:
маршруты:
...
resources :papers do
member do
get 'replies'
end
end
...
тогда, когда ваши маршруты заканчиваются на papers/5/replies
Вы можете вызватьприведенный ниже код в контроллере бумаги:
def replies
@paper = Paper.find(params[:id])
@replies = @paper.questions
end
Вы заметили, что мой код действия на самом деле не нуждается ни в одном из предыдущих идентификаторов маршрута.Я выбираю только params[:id]
, что относится к числу 5. Идентификатор бумажной модели.
Если у вас есть глубокие вложенные маршруты, вы понимаете, что в маршруте есть данные, которые не используются.Действительно важными данными из маршрута является последний параметр.И, возможно, предыдущий парам.
Если вам нужно убедиться, что бумага принадлежит текущему пользовательскому проекту, просто сравните текущего пользователя с идентификатором бумаги, например:
unless current_user.id == Paper.find(params[:id]).project.user.id
redirect_to root_path
И тогда все