La relación Rails HABTM no funciona con la relación polimórfica
Pregunta
Tengo dos modelos:Estudiante y Proyecto.Un estudiante de proyectos HABTM y un proyecto de estudiantes HABTM.Aquí están los dos modelos:
class Student < User
has_many :relationships, dependent: :destroy
has_many :employers, through: :relationships
has_and_belongs_to_many :projects, join_table: :projects_students
end
class Project < ActiveRecord::Base
has_many :relationships
belongs_to :employer
has_and_belongs_to_many :students, join_table: :projects_students
end
Como puede ver, Estudiante usa herencia polimórfica del Usuario (la tabla de usuarios tiene una columna de tipo, uno de los valores es Estudiante).Aquí está el controlador que crea proyectos:
def create
@project = current_user.projects.new(project_params)
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: 'Project was successfully created.' }
format.json { render action: 'show', status: :created, location: @project }
else
format.html { render action: 'new' }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
def project_params
params.require(:project).permit(:title, :category, :location, :budget,
:description, :projectdoc)
end
El proyecto y el estudiante están conectados a través de join_table:projects_students:
create_table "projects_students", force: true do |t|
t.integer "student_id"
t.integer "project_id"
end
add_index "projects_students", ["project_id"], name: "index_projects_students_on_project_id", using: :btree
add_index "projects_students", ["student_id"], name: "index_projects_students_on_student_id", using: :btree
El problema es que cuando se crea un proyecto, el Student_id no se pasa a la tabla proyectos_students.¿Cómo puedo arreglar esto?
Solución
Creo que quiere decir que el estudiante usa la "herencia de una sola mesa" en lugar de "herencia polimórfica" de la cual no existe tal cosa.
Dicho esto, ya que la Asociación de HABTM está en los usuarios y no a los estudiantes, verificaría la consola para ver si esto funciona:
Student.first.projects << Project.first
Lo siguiente que haría es usar "compilación" en lugar de "nuevo" al instancionar el proyecto:
@project = current_user.projects.build project_params
Supongo que esto es solo para crear nuevos proyectos, y que hay una ruta diferente para agregar estudiantes a proyectos.
Otros consejos
Creo que estás pensando mal en esto.Generalmente el _id
está reservado para claves externas de una tabla relacionada.ya que no hay Student
mesa, es posible que los rieles no puedan vincular student_id
en su mesa de unión apropiadamente.
Intente cambiar su tabla de unión:
create_table "projects_users", force: true do |t|
t.integer "user_id"
t.integer "project_id"
end
add_index "projects_users", ["project_id"], name: "index_projects_users_on_project_id", using: :btree
add_index "projects_users", ["user_id"], name: "index_projects_users_on_user_id", using: :btree
Su mesa de unión no debería preocuparse por su configuración de ITS.Puedes manejar eso en tus modelos.
Entonces simplemente limpia las asociaciones:
class Student < User
has_many :relationships, dependent: :destroy
has_many :employers, through: :relationships
has_and_belongs_to_many :projects, join_table: :projects_users, foreign_key: :user_id
end
class Project < ActiveRecord::Base
has_many :relationships
belongs_to :employer
has_and_belongs_to_many :students, join_table: :projects_users, class_name: 'Student', association_foreign_key: :user_id
end