#ruby-on-rails #ruby #associations
#ruby-on-rails #ruby #ассоциации
Вопрос:
У меня есть модель курса:
class Course < ApplicationRecord
has_many :sub_courses
validates :title, presence: true
# Course associated to SubCourse via 'sub_course_id' on Course table
end
И модель подкурса:
class SubCourse < ApplicationRecord
belongs_to :course
# SubCourse associated to Course via 'course_id' on SubCourse table
end
На courses.show.html
(страница конкретного курса, например, admin / courses / 1) у меня есть кнопка, которая ссылается на новую страницу дополнительного курса
%table
%tr
%td= @course.title
%td= @course.description
= button_to "Add New Sub Course", new_admin_sub_course_path(course_id: @course.id), method: :post
Новая форма страницы sub_course sub_courses.new.html
.
= form_for @sub_course, url: admin_sub_courses_path do |f|
= f.label :title
= f.text_field :title
= f.label :description
= f.text_field :description
= f.submit
При переходе на новую страницу дополнительного курса я вижу ошибку No route matches [POST] "/admin/sub_courses/new"
Мой sub_course_controller.rb
выглядит так:
def new
@course = Course.find(params.require(:course_id))
@sub_course = @course.sub_course.new
end
def create
if @sub_course.save
redirect_to admin_sub_courses_path, notice: "saved"
else
render "new"
end
end
И мои маршруты выглядят так:
namespace :admin do
resources :courses, { :only => [:index, :new, :create, :edit, :destroy, :update, :show] }
resources :sub_courses
end
Как мне успешно создать sub_course, который автоматически связан с его курсом с исходной страницы показа, с которой я пришел?
Структура схемы выглядит следующим образом:
create_table "courses", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "title"
t.string "description"
t.integer "sub_course_id"
end
create_table "sub_courses", force: :cascade do |t|
t.string "title"
t.text "description"
t.string "question"
t.string "possible_answer"
t.string "correct_answer"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "course_id"
end
После запуска маршрутов рейка для вспомогательных курсов:
admin_sub_courses GET /admin/sub_courses(.:format) admin/sub_courses#index
POST /admin/sub_courses(.:format) admin/sub_courses#create
new_admin_sub_course GET /admin/sub_courses/new(.:format) admin/sub_courses#new
edit_admin_sub_course GET /admin/sub_courses/:id/edit(.:format) admin/sub_courses#edit
admin_sub_course GET /admin/sub_courses/:id(.:format) admin/sub_courses#show
PATCH /admin/sub_courses/:id(.:format) admin/sub_courses#update
PUT /admin/sub_courses/:id(.:format) admin/sub_courses#update
DELETE /admin/sub_courses/:id(.:format) admin/sub_courses#destroy
Ответ №1:
Прежде всего, я бы проверил результат rake routes |grep sub_courses
.
Однако, на первый взгляд, мне кажется, что существует проблема присвоения значения в sub_course
контроллере. Я бы попытался реорганизовать ее следующим образом:
before_action :set_course, only: [:new, :create]
def new
@sub_course = @course.sub_courses.new
end
def create
@sub_course = @course.sub_courses.new(sub_course_params)
if @sub_course.create!(sub_course_params)
redirect_to admin_sub_courses_path, notice: "saved"
else
render "new"
end
end
private
def sub_course_params
params.require(:sub_course).permit(:title, :description, :question, :possible_answer, :correct_answer, :course_id)
end
def set_course
@course = Course.find(params[:course_id])
end
Как вы видите, я удалил строку с Course.find(params.require(:course_id))
с правильным синтаксисом для поиска записи через параметры.
params.require
Синтаксис вместо этого используется строгими параметрами, которые необходимо определить, чтобы фактически сохранять данные из форм в записи в базе данных.
Смотрите https://api.rubyonrails.org/classes/ActionController/StrongParameters.html
Затем я переместил @course
назначение в частный метод set_course
, таким образом, назначение выполняется только один раз и совместно используется методами, которым это необходимо.
Комментарии:
1. К сожалению, это не решает проблему для меня. Все еще сталкиваясь с ошибкой
No route matches [POST] "/admin/sub_courses/new"
Я думал, что #new никогда не предполагалось, что это СООБЩЕНИЕ? — Я обновил начальный пост маршрутами grep