简体   繁体   English

Simple_form 嵌套资源:未定义的方法

[英]Simple_form nested resources: undefined method

I am new to RoR and I am having trouble with a simple_form with nested resources.我是 RoR 的新手,我在使用带有嵌套资源的 simple_form 时遇到问题。

I have 2 models: Interview & Practice.我有两个模型:面试和实践。 The Interview has_many practices and practices belong_to Interview.面试有_许多实践和实践属于面试。

I am having Action Controller error (undefined method `practices_path' for #<#Class:0x00007fda24ed79d8:0x00007fda24ed5fe8>) when trying to create new practices within the interview_id using simple_form ie.尝试使用 simple_form 在 interview_id 中创建新实践时,我遇到 Action Controller 错误(#<#Class:0x00007fda24ed79d8:0x00007fda24ed5fe8> 的未定义方法 `practices_path'),即。 at this route: /interviews/:interview_id/practices/new)在这条路线上:/interviews/:interview_id/practices/new)

Can anyone help identify what I am doing wrong?谁能帮助确定我做错了什么? Thank you so much in advance.非常感谢你。

Controllers控制器

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

Models楷模

class Interview < ApplicationRecord
  belongs_to :user
  has_many :videos, dependent: :destroy
  has_many :questions, dependent: :destroy
  has_many :practices, dependent: :destroy
  validates :company, :industry, 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

View看法

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

Routes路线

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, only: [:index, :new, :create, :show]
    resources :practices, only: [:index, :new, :create, :show, :destroy]
    resources :videos, only: [:index, :new, :create, :show] do
      resources :reviews, only: [:new, :create]
    end
  end
  resources :candidates, only: [:create, :new, :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

Schema架构

  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", precision: 6, 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.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["interview_id"], name: "index_practices_on_interview_id"
  end

The strange奇怪的

Action Controller error (undefined method `practices_path' for #<#Class:0x00007fda24ed79d8:0x00007fda24ed5fe8>)

error just means that Rails is trying to get the path for [@interview, @practice] (that you're using in your view) but @interview is empty or nil, so the default path for creating a record (in this case @practice) would be practices_path (the form would be a post to /practices).错误只是意味着 Rails 正在尝试获取[@interview, @practice]的路径(您在视图中使用)但 @interview 为空或 nil,因此创建记录的默认路径(在本例中为 @ practice) 将是practices_path (表单将是 /practices 的帖子)。

What you want is simple_form_for to use interviews_practices_path which will convert to /interviews/:interview_id/practices.你想要的是simple_form_for使用interviews_practices_path它将转换为 /interviews/:interview_id/practices。

In your PracticesController action new you also need to initialize a new @interview variable, since you're using that in the view.在您的PracticesController操作new中,您还需要初始化一个新的@interview变量,因为您在视图中使用它。

Since your Practice model is nested, this means that when you go to /interviews/:interview_id/practices/new your ID will be coming from the URL, and is available in params[:interview_id] .由于您的练习Z20F35E630DAF4DBFA4C3F68F5399D8CZ已嵌套,因此,这意味着您Z34D1F91FB2E514B8576FAB1A75A75A89A6BZ to /interviews/:interview_id/practices/new forken_id/forking your your your your y y y y y y y y y y y y y y y y y y y y y y y y y y y params[:interview_id]

So, a simple solution would be to add:因此,一个简单的解决方案是添加:

def new
  @interview = Interview.find(params[:interview_id]
  @practice = Practice.new
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM