Can't destroy record in many-to-many relationship

99封情书 提交于 2019-12-11 02:51:57

问题


I'm new to Rails, so I'm sure I've made a simple mistake.

I've set up a many-to-many relationship between two models: User and Group. They're connected through the junction model GroupMember.

Here are my models (removed irrelevant stuff):

class User < ActiveRecord::Base
  has_many :group_members
  has_many :groups, :through => :group_members
end

class GroupMember < ActiveRecord::Base
  belongs_to :group
  belongs_to :user
end

class Group < ActiveRecord::Base
  has_many :group_members
  has_many :users, :through => :group_members
end

The table for GroupMembers contains additional information about the relationship, so I didn't use has_and_belongs_to_many (as per the Rails "Active Record Associations" guide).

The problem I'm having is that I can't destroy a GroupMember.

Here's the output from rails console:

irb(main):006:0> m = GroupMember.new
=> #<GroupMember group_id: nil, user_id: nil, active: nil, created_at: nil, updated_at: nil>
irb(main):007:0> m.group_id =1
=> 1
irb(main):008:0> m.user_id = 16
=> 16
irb(main):009:0> m.save
=> true
irb(main):010:0> m.destroy
NoMethodError: undefined method `eq' for nil:NilClass
    from /usr/local/lib/ruby/gems/1.8/gems/activesupport-3.0.4/lib/active_support/whiny_nil.rb:48:in `method_missing'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/persistence.rb:79:in `destroy'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/locking/optimistic.rb:110:in `destroy'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/callbacks.rb:260:in `destroy'
    from /usr/local/lib/ruby/gems/1.8/gems/activesupport-3.0.4/lib/active_support/callbacks.rb:413:in `_run_destroy_callbacks'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/callbacks.rb:260:in `destroy'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/transactions.rb:235:in `destroy'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/transactions.rb:292:in `with_transaction_returning_status'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/connection_adapters/abstract/database_statements.rb:139:in `transaction'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/transactions.rb:207:in `transaction'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/transactions.rb:290:in `with_transaction_returning_status'
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.4/lib/active_record/transactions.rb:235:in `destroy'
    from (irb):10

This is driving me crazy, so any help would be greatly appreciated.


回答1:


When you switched from the HABTM relationship to a has_many :through relationship it looks like you may have forgotten to add back the id column. Active record needs GroupMember to have an id for .destroy to work like that.

Look for the :id => false in your migration and get rid of it. then redo the migration.

Hope that helps.




回答2:


I think your group_members table in the database doesnt have a primary key. Maybe you didnt set it up. So, when you create a new GroupMember object and save it, it will not have id. You cannot destroy an object without id(primary key).




回答3:


I ran into the same problems you're describing and your post made me look further for a solution. This is what I found:

1- Get this composite primary keys library from http://compositekeys.rubyforge.org/ 2- Add it to your gem file 3- Add the following to GroupMember set_primary_keys [:user_id, :group_id]

  • note set_primary_keys and not set_primary_key

this will return the right primary when you call GroupMember.primary_key when destroy looks for .primary_key , it'll now find it.

Try it in your console: gm = GroupMember.first gm.destroy

I hope this helps =)




回答4:


If you are using associations and for whatever reason chose not to use Active Records default id, you can set the default id using "set_primary_key" so methods like find and destroy work properly.

class User < ActiveRecord::Base
  set_primary_key :user_primary
  has_many :group_members, :dependent => :destroy
  has_many :groups, :through => :group_members
end

class GroupMember < ActiveRecord::Base
  set_primary_key :group_member_primary
  belongs_to :group
  belongs_to :user
end

class Group < ActiveRecord::Base
  set_primary_key :group_primary
  has_many :group_members, :dependent => :destroy
  has_many :users, :through => :group_members
end



回答5:


Have you tried m.reload.destroy instead of m.destroy, to see what happens?



来源:https://stackoverflow.com/questions/5085258/cant-destroy-record-in-many-to-many-relationship

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