问题
schema.rb:
ActiveRecord::Schema.define(version: 20150324012404) do
create_table "groups", force: :cascade do |t|
t.string "title"
t.integer "teacher_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "groups_students", id: false, force: :cascade do |t|
t.integer "group_id"
t.integer "student_id"
end
add_index "groups_students", ["group_id"], name: "index_groups_students_on_group_id"
add_index "groups_students", ["student_id"], name: "index_groups_students_on_student_id"
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "admin", default: false
t.string "type"
t.integer "group_id"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
group.rb:
class Group < ActiveRecord::Base
belongs_to :teacher
has_and_belongs_to_many :students
end
student.rb:
class Student < User
has_and_belongs_to_many :groups
end
I could have set a simple belongs_to and a has_many relationship between the student and group models, but I want students to be able to belong to more than one group, so I set up a HABTM association and corresponding join table.
I think I that right?
The question is, how do I, in the console, set a Student to belong to more than one group?
I have setup a User with 'type: Student' and I have two Groups. So...
In the console I do:
student = Student.first
Then, I want to set 'student' to belong to both Groups, but I don't know how to do this.
To set it to belong to one group I can do:
student.update_attributes(group_id: 1)
But how do make it belong to both groups? It would have two group_id's wouldn't it? I don't know how to set this.
If you need to see any of the other files, it's the 'handcode' branch here: https://github.com/Yorkshireman/sebcoles/tree/handcode
回答1:
The answers others have already provided are correct. But if you're working with id's you can also do something like this
student = Student.first
student.group_ids = 1,2,3,4
回答2:
You don't need to set group_id for the User, the association is handled by the join table and the HABTM statement. You should remove group_id from the users table in the schema.
From memory you should be able to do something like this:
student = Student.first
groups = Group.all
student.groups << groups
student.save
See the active record guide on HABTM associations - specfically 4.4.1.3
回答3:
Instead of habtm, just use the normal through and your life becomes easy. Make sure an id is generated for the association table (remove id:false)
create_table "group_students", force: :cascade do |t|
t.integer :group_id, nil:false
t.integer :student_id, nil:false
end
class Group < ActiveRecord::Base
has_many :group_students, dependent: :destroy, inverse_of :group
has_many :students, through :group_students
end
class Student < ActiveRecord::Base
has_many :group_students, dependent: :destroy, inverse_of :student
has_many :groups, through: :group_students
end
class GroupStudent < ActiveRecord::Base
belongs_to :group,
belongs_to :student
validates_presence_of :group, :student
end
Group.last.students << Student.last
or..
Student.last.groups << Group.last
Student.last.groups = [Group.find(1), Group.find(2)]
etc....
回答4:
Ok, so it took me 3 days of all kinds of pain to work this out.
There was nothing wrong with my original code, except that I needed to remove the group_id from the user table.
roo's answer was correct, except that using 'group' as a variable name in the console confused Rails. This had led me to believe there was something wrong with my code, but there wasn't. You learn the hard way.
So, Students can be pushed into Groups like this:
To push a student into one group:
student = Student.first
OR
student = Student.find(1)
(or whatever number the id is)
group1 = Group.first
OR
group1 = Group.find(1)
student.groups << group1
To push into multiple groups (which was the original goal of this whole debacle:
student = Student.first
OR
student = Student.find(1)
allclasses = Group.all
student.groups << allclasses
To view your handywork:
student.groups
Works beautifully. The only problem I can see with my code is that it's possible to push the same student into a group twice, resulting in two duplicates of that student in one group. If anyone knows how to prevent this happening, I'm all ears.
来源:https://stackoverflow.com/questions/29223974/rails-4-habtm-how-to-set-multiple-ids-in-console