0

I am trying to create an association between two tables. A student table and a computer table. A computer can only ever be assigned to one student (at any one time) but a student can be assigned to multiple computers.

This is what I currently have in mind. Setting up a has-many through relationship and modifying it a bit.

class Student < ActiveRecord::Base
  has_many :assignemnts
  has_many :computers, :through => :assignments
end

class Computer < ActiveRecord::Base
 has_one :assignment
 has_one :student, :through => :assignments
end

class Assignment < ActiveRecord::Base
  belongs_to :student
  belongs_to :computer
end

Does this seem like the best way to handle this problem? Or something better sound out quickly to the experts here. Thanks!

Dan
  • 2,299
  • 2
  • 20
  • 41

3 Answers3

1

You need first to decide if a simple one-to many relationship is enough for you.

If yes, it gets a lot easier, because you can get rid of the Assignment-class and table.

Your database-table "computers" then needs a student_id column, with a non-unique index

Your models should look like this:

class Computer < ActiveRecord::Base
    belongs_to :student
end

class Student < ActiveRecord::Base
    has_many :computers, :dependent => :nullify
end

"dependent nullify" because you don't want to delete a computer when a student is deleted, but instead mark it as free.

Each of your computers can only be assigned to a single student, but you can reassign it to a different student, for example in the next year.

Meier
  • 3,858
  • 1
  • 17
  • 46
0

You can also use has_and_belongs_to_many method. In your case it will be:

class Student < ActiveRecord::Base
    has_many :assignemnts
    has_and_belongs_to_many :computers, :join_table => 'assignments',
end

class Computer < ActiveRecord::Base
    has_one :assignment
    has_and_belongs_to_many :student, :join_table => 'assignments',
end

or you can rename assignments table to computers_students and remove join_table

class Student < ActiveRecord::Base
    has_many :assignemnts
    has_and_belongs_to_many :computers
end

class Computer < ActiveRecord::Base
    has_one :assignment
    has_and_belongs_to_many :student
end
alexkv
  • 5,144
  • 2
  • 21
  • 18
0

Actually your approach is fine, as one offered by @alexkv. It is more discussion, than question.

Another thing if you want to use mapping table for some other purposes, like storing additional fields - then your approach is the best thing. In has_many :through table for the join model has a primary key and can contain attributes just like any other model.

From api.rubyonrails.org:

Choosing which way to build a many-to-many relationship is not always simple. If you need to work with the relationship model as its own entity, use has_many :through. Use has_and_belongs_to_many when working with legacy schemas or when you never work directly with the relationship itself.

I can advise you read this, to understand what approach better to choose in your situation:

thesis
  • 2,565
  • 5
  • 26
  • 37