我的問題
我正在嘗試通過我的 Ruby on Rails 應用程式中的外鍵關聯來檢索資料。主表中的資料已正確加載,但關聯的物件未加載且始終為nil。
背景資訊(遷移、資料庫表和模型類)
我目前正在處理兩個表:
- eval_forms
- 用戶詳細資訊
這些表是通過 Rails 遷移創建的。
user_details 表是通過一次遷移創建的:
class CreateUserDetails < ActiveRecord::Migration[5.2]
def change
create_table :user_details do |t|
t.string :eduPersonPrincipalName, unique: true
t.string :DisplayName, default: 'NULL'
t.string :Email, default: 'NULL'
t.string :Role, default: 'Student'
t.boolean :hasAppointment, default: '0'
t.timestamps
end
end
def self.down
drop_table :user_details
end
end
并且 eval_forms 表有一些遷移來創建和更新它:
class CreateEvalForms < ActiveRecord::Migration[6.1]
def change
create_table :eval_forms do |t|
t.belongs_to :form_builder, foreign_key: 'form_builder_id'
t.belongs_to :course, foreign_key: 'course_id'
t.string :Description
t.datetime :OpenDate
t.datetime :CloseDate
t.timestamps
end
end
end
class UpdateEvalForms < ActiveRecord::Migration[6.1]
def change
add_column :eval_forms, "Author_user_details_id", :bigint, null: false
add_foreign_key :eval_forms, :user_details, column: "Author_user_details_id"
add_column :eval_forms, "Year", :integer
add_column :eval_forms, "Semester", :string
add_column :eval_forms, "IsArchived", :boolean
end
end
我知道外鍵設定正確,因為它在 MySQL 中正確列出。這是來自 MySQL 的 2 個表及其關系的參考:

此外,我已經在我的 Rails 應用程式中設定了模型類。
評估表格:
class EvalForm < ApplicationRecord
has_many :eval_forms_roles
has_many :roles, through: :eval_forms_roles
has_many :eval_forms_courses
has_many :courses, through: :eval_forms_courses
has_many :eval_responses
has_many :eval_reminders
belongs_to :user_detail
validates :formName, presence: true
validates :formData, presence: true
end
user_detail:
class UserDetail < ApplicationRecord
has_one :la_detail
has_many :eval_responses
has_many :eval_forms
end
So What's Wrong?
Lastly, here is the code to retrieve the objects from the database and the section where I'm getting my error.
My controller action:
def index
# list *all* existing evaluation forms, with options to filter by OpenDate, CloseDate, etc (todo)
@EvalForms = EvalForm.includes(:user_detail)
end
My view:
<td><%= ef.user_detail.DisplayName %></td>
My error:
NoMethodError in Evaluations::EvalForms#index
undefined method `DisplayName' for nil:NilClass
Extracted Source location: <td><%= ef.user_detail.DisplayName %></td>
Restating the problem
In conclusion, I'm really confused as to why the associated user_detail objects are not being retrieved despite my .includes() statement in the controller action. I'm pretty new to Ruby as well as Rails, but there are other sections in the application that look similar to this and work correctly so I don't see what my issue is.
uj5u.com熱心網友回復:
我將從使用常規命名開始,這在 Rails 中意味著無處不在的蛇形:
class CreateUserDetails < ActiveRecord::Migration[5.2]
def change
create_table :user_details do |t|
t.string :edu_person_principal_name, unique: true
t.string :display_name
t.string :email
t.string :role, default: 'Student'
t.boolean :has_appointment, default: false # let the driver handle conversion
t.timestamps
end
end
end
class UpdateEvalForms < ActiveRecord::Migration[6.1]
def change
change_table :eval_forms do |t|
t.belongs_to :author_user_details, foreign_key: { to_table: :user_details }
t.integer :year # consider using `YEAR(4)` instead
t.string :semester
t.boolean :is_archived, default: false
end
end
end
如果繼續使用的一個奇怪的混合camelCase和PascalCase你需要明確地配置所有的相關專案,你將失去約定優于配置的所有優點。我根本不會推薦這個,除非你堅持使用遺留資料庫,因為它是開發人員混淆和錯誤的必經之路。
如果您在PascalCase沒有明確接收者(自我)的情況下呼叫方法,您也會得到一個缺失的常量錯誤:
class EvalForm < ApplicationRecord
def short_description
# uninitialized constant Description (NameError)
Description.truncate(27, separator: ' ')
end
end
雖然你可以解決這個問題,但self.Description.truncate(27, separator: ' ')它仍然很臭。
在這種情況下,如果要呼叫列author_user_details_id而不是user_details_id從名稱派生的列,則需要將關聯配置為使用非常規名稱:
class EvalForm < ApplicationRecord
belongs_to :user_detail, foreign_key: :author_user_details_id
end
class UserDetail < ApplicationRecord
has_many :eval_forms, foreign_key: :author_user_details_id
end
如果您的架構的其余部分看起來像這樣,您將必須全面執行此操作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/342932.html
上一篇:尋找各種給人們分配水果的方法
