【问题标题】:Rails Associations - Creating a new record through a form with belongs_toRails 关联 - 通过带有 belongs_to 的表单创建新记录
【发布时间】:2020-09-14 12:17:47
【问题描述】:

我有一个课程模型:

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_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

如何从我来自的原始显示页面成功创建与其课程自动关联的子课程?

架构结构如下所示:

  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

为子课程运行 rake 路线后:

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

【问题讨论】:

    标签: ruby-on-rails ruby associations


    【解决方案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 这样赋值只完成一次,并由需要它的方法共享。

    【讨论】:

    • 不幸的是,这并不能解决我的问题。仍然遇到错误No route matches [POST] "/admin/sub_courses/new" 我认为#new 永远不会被认为是 POST? - 我用 grep 路线更新了最初的帖子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多