Отношения Rails HABTM не работают с полиморфными отношениями

У меня есть две модели: Student и Project. Студенческие проекты HABTM и студенты проекта HABTM. Вот две модели:

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

Как видите, Student использует полиморфное наследование от User (в таблице user есть столбец type, одно из значений — Student). Вот контроллер, который создает проекты:

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

Project и Student связаны через 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

Проблема в том, что когда создается проект, student_id не передается в таблицу project_students. Как я могу это исправить?




Ответы (2)


Я думаю, вы хотите сказать, что Студент использует «наследование одной таблицы», а не «полиморфное наследование», которого нет.

Тем не менее, поскольку ассоциация HABTM предназначена для пользователей, а не для студентов, я бы проверил консоль, чтобы увидеть, работает ли это:

Student.first.projects << Project.first

Следующее, что я бы сделал, это использовать «сборку» вместо «нового» при создании экземпляра проекта:

@project = current_user.projects.build project_params

Я предполагаю, что это только для создания новых проектов, и что есть другой способ добавления студентов в проекты.

person davidfurber    schedule 15.11.2013
comment
В консоли работает. Я пытался указать это в сильных параметрах, но это не сработало. Нет списка флажков. Когда учащийся подает заявку на участие в проекте, вышеописанному методу создания завидуют, и я хочу, чтобы этот учащийся был student_id. - person Philip7899; 15.11.2013
comment
Понимаю. Я думаю, что вы должны использовать build вместо new при создании экземпляра нового проекта. - person davidfurber; 15.11.2013
comment
Какая разница? - person Philip7899; 15.11.2013
comment
Build создает экземпляр объекта с набором ассоциаций. - person davidfurber; 15.11.2013

Я думаю, вы думаете об этом неправильно. Обычно _id зарезервирован для внешних ключей связанной таблицы. Поскольку таблицы Student нет, rails может быть не в состоянии правильно связать student_id в вашей таблице соединений.

Попробуйте изменить таблицу соединений:

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

Ваша таблица присоединения не должна заботиться о настройке STI. Вы можете справиться с этим в своих моделях.

Тогда просто очистите ассоциации:

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
person codenamev    schedule 15.11.2013