【问题标题】:Insert into associative table not allowed without "optional: true"?如果没有“可选:true”,则不允许插入关联表?
【发布时间】:2018-10-21 00:44:47
【问题描述】:

我正在为我的一门课程开发一个 Ruby on Rails 项目,我当前的任务要求我允许用户注册课程。我有三个模型,用户、课程和属于两者的关联连接表,即注册。当前各模型的rb文件中的设置如下:

class Enrollment < ApplicationRecord
  belongs_to :user
  belongs_to :course
end

class Course < ApplicationRecord
  has_many :enrollments
  has_many :users, through: :enrollments
end

class User < ApplicationRecord
  has_many :enrollments
  has_many :courses, through: :enrollments
end

主要问题是,每当我尝试从 rails 控制台向 Enrollment 模型添加新条目时,都会出现错误提示:

[4] pry(main)> enrollment = Enrollment.new(u_id: 1, c_id: 1)
=> #<Enrollment:0x00007f94bc771020 id: nil, u_id: 1, c_id: 1, ...>
[5] pry(main)> enrollment.save
  (0.1ms)  begin transaction
  (0.1ms)  rollback transaction
=> false
[6] pry(main)> enrollment.errors

=> #<ActiveModel::Errors:0x00007f94bc7c7290
@base=#<Enrollment:0x00007f94bc771020 id: nil, u_id: 1, c_id: 1, created_at:
nil, updated_at: nil>,
@details={:user=>[{:error=>:blank}], :course=>[{:error=>:blank}]},
@messages={:user=>["must exist"], :course=>["must exist"]}>

它声称用户和课程必须存在,但两个模型都已填充并单独工作。但是,通过将我的 registration.rb 更改为:

class Enrollment < ApplicationRecord
  belongs_to :user, optional: true
  belongs_to :course, optional: true
end

它允许我添加一个新的注册条目就好了。有谁知道为什么我需要“可选:真”才能使其工作?有谁知道在不使用“可选:真”的情况下解决此问题的方法?任何帮助,将不胜感激。我也愿意详细说明,所以请告诉我。

谢谢!

【问题讨论】:

    标签: ruby-on-rails database activerecord


    【解决方案1】:

    您使用的外键与您在关联中定义的外键以及使用 rails 约定时的预期不同。

    根据 Rails 约定,table_name_id 应定义为列。 所以在你的情况下,它应该是 course_iduser_id,因为你正在与 course 模型和 user 模型建立关联。

    它期望 course_iduser_id 作为外键,但您已将外键定义为 c_idu_id

    要解决这个问题,您必须通过明确告诉它使用这些外键而不是它的假设来覆盖 Rails 约定。

    对您的注册模型进行一些更改

    class Enrollment < ApplicationRecord
      belongs_to :user, class_name: 'User', foreign_key: 'u_id'
      belongs_to :course, class_name: 'Course', foreign_key: 'c_id'
    end
    

    现在您可以删除可选的 true。

    【讨论】:

    • 或在迁移中将列重命名为user_idcourse_id。使用缩写的列名不是一个好主意,最终会出现很多a_id、b_id、c_id,非常不方便。
    • @Vasilisa 确实!
    • 非常感谢加根!现在这很有意义。我进行了更改,现在它正在工作。给你最好的!
    猜你喜欢
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多