Rails 4 HABTM how to set multiple ids in console?

十年热恋 提交于 2019-12-12 06:13:06

问题


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:

  1. 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
  1. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!