这是我在完成项目时遇到的完整错误:
没有路线匹配{:action =>" show",:controller =>" teacher",:id =>" 3",&gt ;:school_id => nil}缺少必需的键:[:school_id]
以下是导致错误的行:
@teacher = Teacher.find(params[:teacher_id])
@rating = @teacher.ratings.create(rating_params)
redirect_to school_teacher_path(@school, @teacher)
end
private
这是我的路线档案:
Rails.application.routes.draw do
get 'users/new'
resources :schools do
resources :teachers
end
resources :users do
resources :ratings
end
resources :teachers do
resources :ratings
end
这是我的ratings_controller.rb:
def new
@teacher = Teacher.find(params[:teacher_id])
rating = Rating.new
end
def create
@teacher = Teacher.find(params[:teacher_id])
@rating = @teacher.ratings.create(rating_params)
redirect_to school_teacher_path(@school, @teacher)
end
private
def rating_params
params.require(:rating).permit(:student, :helpfulness,:clarity,:easiness, :comment)
end
如果我理解正确,是不是因为我没有在我的路线文件中嵌套评级资源?我怎样才能防止将来发生这种错误?
提前感谢您,祝您度过愉快的一天。
答案 0 :(得分:3)
错误很明显。您需要为嵌套路线提供school_id
,但不要设置@school
变量,因此它是nil
。这应该有效:
redirect_to school_teacher_path(@teacher.school, @teacher)
或
redirect_to [@teacher.school, @teacher]
当然。您应该在school
模块中拥有Teacher
关联。
答案 1 :(得分:2)
redirect_to school_teacher_path(@school, @teacher)
您没有@school
可用(您尚未定义)。
您需要明确设置@school
,或者提及@Marek
,您应该使用school
上的Teacher
关联:
@teacher = Teacher.find params[:teacher_id]
@school = ? #=> could be @teacher.school
@rating = @teacher.ratings.create rating_params
为了给你一些背景信息,这里有关于模型/协会的一些信息。它们如何适合您的应用:
#app/models/teacher.rb
class Teacher < ActiveRecord::Base
has_many :ratings
has_many :schools, through: :ratings
end
#app/models/rating.rb
class Rating < Activerecord::Base
belongs_to :teacher
belongs_to :school
belongs_to :user #-> this does not feature in the has_many :through
end
#app/models/school.rb
class School < ActiveRecord::Base
has_many :ratings
has_many :teachers, through: :ratings
#only problem here is there is no "central" record of teachers & schools
end
这使您能够调用以下内容:
@teacher = Teacher.find x
@teacher.ratings
@school = School.find y
@school.ratings
@ratings = Rating.where(teacher: @teacher)
@ratings = Rating.where(school: @school)
@teacher.rating.school #-> "school" for rating
现在,需要注意的重要一点是,此设置完全在您的模型中。
Rails是 MVC (Model View Controller)框架 -
这意味着您的所有“数据”逻辑应保存在模型,控制器&amp; views 应管理该数据以为用户创建输出。
-
许多新手不理解“模型”,“控制器”和“视图”之间的区别。以下是它的工作原理:
Rails基于Ruby构建。 Ruby是object orientated
OOP(面向对象编程)只是意味着用类数据填充变量,包含“属性”和“方法”。然后可以将该变量称为对象,同时从中调用这两个属性,以及用于对其执行操作的方法。
OOP主要用于游戏:
...它允许您一次在应用程序中保留大量动态数据。在游戏的示例中,这意味着您可以根据用户与游戏的交互来调用多个对象。
在马里奥,例如,每个“敌人”都会有一定的“路径”,每次玩家“移动”马里奥(IE马里奥对象的位置被重绘),如果它与其中一个敌人相交,马里奥对象将使他的健康状况耗尽。
在 Rails 中,我们没有豪华的有状态应用程序(HTTP is stateless)。无状态应用程序(Rails是)每次用户发送请求时都必须重建“环境”。
这意味着您必须确保每次在用户系统上接受请求时都能够重建所需的数据对象。因此,如果您有redirect_to school_teacher_path(@school, @teacher)
,则需要存在@school
和@teacher
个对象才能生效。
-
重建“环境”是控制器的用途 - 它们接受用户的请求,从模型中提取数据并将其纳入视图。
当请求完成后,控制器然后将编译的HTML发送回浏览器,允许用户查看更新的响应。发生错误是因为您没有在控制器中构建正确的数据。
应用中的Everything 应该适合让您的数据编译过程在控制器中正常运行。甚至是路线:
#config/routes.rb
resources :teachers do
resources :ratings #-> url.com/teachers/:teacher_id/ratings/:id
end
以上允许您传递以下内容:
#app/controllers/ratings_controller.rb
class RatingsController < ApplicationController
def show
@teacher = Teacher.find params[:teacher_id]
@rating = @teacher.ratings.find params[:id]
end
end