Не может уничтожить запись в отношениях многих ко многим - PullRequest
2 голосов
/ 23 февраля 2011

Я новичок в Rails, поэтому я уверен, что совершил простую ошибку.

Я установил отношения «многие ко многим» между двумя моделями: User и Group. Они связаны через соединительную модель GroupMember.

Вот мои модели (удалены ненужные вещи):

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

Таблица для GroupMembers содержит дополнительную информацию об отношениях, поэтому я не использовал has_and_belongs_to_many (согласно руководству Rails «Ассоциации активных записей»).

У меня проблема в том, что я не могу уничтожить GroupMember.

Вот вывод из консоли rails:

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

Это сводит меня с ума, поэтому любая помощь будет принята с благодарностью.

Ответы [ 5 ]

5 голосов
/ 25 февраля 2011

Когда вы переключаетесь с отношения HABTM на отношение has_many: через отношение это выглядит так, как будто вы забыли добавить обратно столбец id.Активная запись нуждается в GroupMember, чтобы иметь идентификатор .destroy для такой работы.

Найдите :id => false в своей миграции и избавьтесь от него.затем повторите миграцию.

Надеюсь, это поможет.

0 голосов
/ 25 июня 2011

Если вы используете ассоциации и по какой-либо причине решили не использовать идентификатор по умолчанию Active Records, вы можете установить идентификатор по умолчанию, используя "set_primary_key", чтобы такие методы, как поиск и уничтожение, работали правильно.

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
0 голосов
/ 20 марта 2011

Я столкнулся с теми же проблемами, которые вы описываете, и ваш пост заставил меня искать дальнейшее решение. Вот что я нашел:

1 - Получить эту составную библиотеку первичных ключей от http://compositekeys.rubyforge.org/ 2- Добавьте его в свой гем-файл 3- Добавьте следующее в GroupMember set_primary_keys [: user_id,: group_id]

  • примечание set_primary_keys, а не set_primary_key

это вернет правильный основной при вызове GroupMember.primary_key когда destroy ищет .primary_key, теперь он его найдет.

Попробуйте в своей консоли: gm = GroupMember.first gm.destroy

Надеюсь, это поможет =)

0 голосов
/ 25 февраля 2011

Я думаю, что ваша таблица group_members в базе данных не имеет первичного ключа.Может быть, вы не настроили это.Поэтому, когда вы создаете новый объект GroupMember и сохраняете его, у него не будет идентификатора.Вы не можете уничтожить объект без идентификатора (первичный ключ).

0 голосов
/ 25 февраля 2011

Вы пытались m.reload.destroy вместо m.destroy, чтобы увидеть, что происходит?

...