问题描述
我是 RoR 的新手,我在使用带有嵌套资源的 simple_form 时遇到了问题。
我有两个模型:面试和练习。面试有_许多实践和实践属于_面试。
我在尝试使用 simple_form 在interview_id 中创建新实践时遇到Action Controller 错误(未定义方法`practices_path' for #)。在这条路线上:/interviews/:interview_id/practices/new)
谁能帮助确定我做错了什么?在此先感谢您。
控制器
class PracticesController < ApplicationController
def index
@practices = Practice.all
end
def new
@practice = Practice.new
end
def create
@interview = Interview.find(params[:interview_id])
@practice = Practice.new(practice_params)
@practice.interview = @interview
if @practice.save
redirect_to new_interview_practice_path(@interview)
else
render 'new'
end
end
# def destroy
# @interview = Interview.find(params[:id])
# @question.interview = @interview
# @question.destroy
# redirect_to interview_questions_path(@interview)
private
def practice_params
params.require(:practice).permit(:question,:type,:title)
end
end
class InterviewsController < ApplicationController
def index
@interviews = Interview.all
end
def new
@interview = Interview.new
end
def create
@interview = Interview.new(interview_params)
@interview.user = current_user
if @interview.save
redirect_to interview_path(@interview)
end
end
def show
@interview = Interview.find(params[:id])
@question = Question.new
end
def destroy
@interview = Interview.find(params[:id])
@interview.destroy
redirect_to interviews_path
end
private
def interview_params
params.require(:interview).permit(:company,:industry,:photo)
end
end
模型
class Interview < ApplicationRecord
belongs_to :user
has_many :videos,dependent: :destroy
has_many :questions,dependent: :destroy
has_many :practices,dependent: :destroy
validates :company,presence: true
has_one_attached :photo
def days_remaining
-(Date.today - self.final_date.to_date).to_i if self.final_date
end
include PgSearch::Model
pg_search_scope :search_by_name_and_date,against: [:name,:open_date,:final_date,:company],using: {
tsearch: { prefix: true }
}
end
class Practice < ApplicationRecord
belongs_to :interview
has_many :questions,through: :interviews
end
查看
<br>
<div class="text-center">
<h3>Lets create a new practice interview!</h3>
</div>
<div class="form-container">
<%= simple_form_for [@interview,@practice] do |f| %>
<div class="flex-container2">
<div class="form-style-5">
<legend><span class="number">1</span> Job Info</legend>
<%= f.input :title,placeholder: "give it a name"%>
<%= f.input :type,placeholder: "Competency"%>
<%= f.input :question,placeholder: "add here" %>
</div>
</div>
<div class="row d-flex justify-content-center mb-5">
<div class="col-md-7">
<%= f.submit class: "btn btn-primary"%>
</div>
</div>
<% end %>
</div>
路线
Rails.application.routes.draw do
devise_for :users
root to: 'pages#home'
get 'dashboard',to: 'users#dashboard'
get 'calendar',to: 'pages#calendar'
get 'video',to: 'pages#video'
get 'settings',to: 'pages#settings'
post 'sendsms',to: 'videos#send_sms'
resources :interviews,only: [:index,:new,:create,:show,:destroy] do
resources :questions,:show]
resources :practices,:destroy]
resources :videos,:show] do
resources :reviews,only: [:new,:create]
end
end
resources :candidates,only: [:create,:show]
resources :searches
get 'thank_you',to: 'videos#thank_you'
# For details on the DSL available within this file,see https://guides.rubyonrails.org/routing.html
end
架构
create_table "interviews",force: :cascade do |t|
t.datetime "open_date"
t.datetime "final_date"
t.bigint "user_id",null: false
t.datetime "created_at",precision: 6,null: false
t.datetime "updated_at",null: false
t.string "name"
t.string "company"
t.string "industry"
t.index ["user_id"],name: "index_interviews_on_user_id"
end
create_table "practices",force: :cascade do |t|
t.string "title"
t.string "type"
t.text "question"
t.bigint "interview_id",null: false
t.index ["interview_id"],name: "index_practices_on_interview_id"
end
解决方法
奇怪的
Action Controller error (undefined method `practices_path' for #<#Class:0x00007fda24ed79d8:0x00007fda24ed5fe8>)
error 只是意味着 Rails 正在尝试获取 [@interview,@practice]
的路径(您在视图中使用的)但 @interview 为空或 nil,因此创建记录的默认路径(在这种情况下) @practice) 将是 practices_path
(表单将是 /practices 的帖子)。
您想要的是 simple_form_for
使用 interviews_practices_path
将转换为 /interviews/:interview_id/practices。
在您的 PracticesController
操作 new
中,您还需要初始化一个新的 @interview
变量,因为您正在视图中使用它。
由于您的练习模型是嵌套的,这意味着当您转到 /interviews/:interview_id/practices/new
时,您的 ID 将来自 URL,并且在 params[:interview_id]
中可用。
因此,一个简单的解决方案是添加:
def new
@interview = Interview.find(params[:interview_id]
@practice = Practice.new
end