0

目前有主要的 Rails 问题。我正在创建一个 School-Dashboard 应用程序,该应用程序采用一个名为 Enrollments 的外部参照表,该表与课程和学生相关联。

每当我尝试更新入学成绩时,我都会不断收到这条线

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: UPDATE
"enrollments" SET "grade" = ?, "updated_at" = ? WHERE "enrollments"."" IS NULL

当我更新课程或学生的属性时,此行不会出现。仅适用:grade于 Enrollment 中的属性。出于某种原因,它没有被正确读取,即使它是我的数据库中用于注册的合法属性(查看我的模式)。

我在 Rails 沙箱中完成了所有的初步工作。 使用 ruby​​ 2.1.1,Rails 4.1.0.rc1

我真的很想在这里得到一些帮助。

这是我对应的模型

class Student < ActiveRecord::Base
   has_many :enrollments
   has_many :courses, through: :enrollments
end

class Course < ActiveRecord::Base
   has_many :enrollments
   has_many :students, through: :enrollments
end

class Enrollment < ActiveRecord::Base
    belongs_to :student
    belongs_to :course
end

控制器:

学生

class StudentsController < ApplicationController
   def index
      @students = Student.all
   end

   def new
      @student = Student.new
   end

   def show
   end

   def update
      @student.update_attributes(student_params) ? redirect_to @student : render 'edit'
   end

   def create
      @student = Student.new(student_params)
      @student.save ? redirect_to @student : render 'new' 
   end

   def destroy
   end

   def edit
   end

   private
   def student_params
      params.require(:student).permit(:first_name, :last_name, :student_number, :email)
  end
 end

培训班

class CoursesController < ApplicationController
   def index
     @courses = Course.all
   end

   def new
     @course = Course.new
   end

   def show
   end

   def update
     @course.update_attributes(course_params) ? redirect_to @course : render 'edit'
   end

   def create
     @course = Course.new(course_params)
     @course.save ? redirect_to @course : render 'new'
   end

   def destroy
   end

   def edit
     # code here
   end

   private
   def course_params
     params.require(:course).permit(:course_name, :course_number)
   end
 end

招生

class EnrollmentsController < ApplicationController
   attr_accessor :course_id, :student_id, :grade
   def index
     @enrollments = Enrollment.all
   end

   def new
     @enrollment = Enrollment.new
   end

   def create
     @enrollment = Enrollment.new(enrollment_params)
     @enrollment.save ? redirect_to @enrollment : render 'new'
   end

   def update
     @enrollment.update_attributes(enrollment_params) ? redirect_to @enrollment : render  'edit'
   end

   def show
   end

   def destroy
     @enrollment.destroy
   end

   def edit
     # code here
   end

   private
   def enrollment_params
     params.require(:enrollment).permit(:course_id, :student_id, :grade)
   end
 end

最后是我的 schema.rb

 ActiveRecord::Schema.define(version: 20140417152720) do

   create_table "courses", force: true do |t|
     t.string   "course_name"
     t.integer  "course_number"
     t.datetime "created_at"
     t.datetime "updated_at"
   end

   create_table "enrollments", id: false, force: true do |t|
     t.integer  "course_id",                          null: false
     t.integer  "student_id",                         null: false
     t.decimal  "grade",      precision: 5, scale: 2
     t.datetime "created_at"
     t.datetime "updated_at"
   end

   # noinspection RailsParamDefResolve
   add_index "enrollments", ["course_id", "student_id"], name: "index_enrollments_on_course_id_and_student_id"
   # noinspection RailsParamDefResolve
   add_index "enrollments", ["student_id", "course_id"], name: "index_enrollments_on_student_id_and_course_id"

   create_table "students", force: true do |t|
     t.string   "first_name"
     t.string   "last_name"
     t.string   "email"
     t.integer  "student_number"
     t.datetime "created_at"
     t.datetime "updated_at"
   end
 end
4

1 回答 1

2

看来是我自己想出来的!

所以这里有一些需要解决的rails约定。问题出在我的“注册”数据库设置上。当我运行命令时,
rails g migration CreateJoinTableEnrollments course student
Rails 在我的迁移文件中为我做了太多的工作(除了表名和等级,我添加了)

class CreateJoinTableEnrollments < ActiveRecord::Migration
  def change
     create_join_table :courses, :students, table_name: :enrollments, id: false, force: true do |t|
       t.index [:course_id, :student_id], null: false
       t.index [:student_id, :course_id], null :false
       t.decimal :grade, precision: 5, scale: 2
       t.timestamps
    end
   end
 end

实际上,我不需要这些。为了操作注册行中的特定数据,该行必须有一个标识符。有了id: false, force: true那个选项就被取消了。我还通过索引简化了事情。我只是创建了常规的旧列。现在我的迁移文件看起来像这样。

class CreateJoinTableEnrollments < ActiveRecord::Migration
   def change
      create_table :enrollments do |t|
         t.integer :course_id, null: false
         t.integer :student_id, null: false
         t.decimal :grade, precision: 5, scale: 2

         t.timestamps
      end
    end
  end

有了这个,没有问题!在过去的两天里,我一直在为此烦恼。希望这对遇到此问题的其他人有所帮助。

于 2014-04-18T18:05:54.463 回答