Question

I have two models: Student and Project. A student HABTM projects and a Project HABTM students. Here are the two models:

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

As you can see, Student uses polymorphic inheritance from User (The user table has a type column, one of the values is Student). Here is the controller that creates projects:

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 and Student are connected through the 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

The problem is that when a project is created, the student_id is not being passed to the projects_students table. How can I fix this?

Was it helpful?

Solution

I think you mean to say that Student uses "single table inheritance" rather than "polymorphic inheritance" of which there is no such thing.

That said, since the HABTM association is on users and not students, I'd check in the console to see if this works:

Student.first.projects << Project.first

Next thing I'd do is to use "build" instead of "new" when instantiating the project:

@project = current_user.projects.build project_params

I suppose this is only for creating new projects, and that there is a different route for adding students to projects.

OTHER TIPS

I think you're thinking about this wrong. Generally the _id is reserved for foreign keys to a related table. Since there is no Student table, rails may be unable to link the student_id in your join table appropriately.

Try changing your join table:

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

Your join table shouldn't care about your STI setup. You can handle that in your models.

So then just cleanup the associations:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top