Как определить allow_destroy и: зависимый =>: уничтожить в Rails? - PullRequest
6 голосов
/ 23 марта 2011

Учитывая следующую модель базы данных, как и где вы бы определили отношения удаления между моделями?Я выяснил базовую настройку ассоциации таблиц, но когда я хочу добавить зависимости для включения удаления вложенных объектов , я теряюсь.

Database relationship model

Вотмодель отношений, которую я создал.

class User < ActiveRecord::Base
  has_many :studies
end

class Study < ActiveRecord::Base
  has_many :internships
  belongs_to :student, :class_name => "User", :foreign_key => "user_id"
  belongs_to :subject
  belongs_to :university, :class_name => "Facility", :foreign_key => "facility_id"
  accepts_nested_attributes_for :subject, :university, :locations
end

class Subject < ActiveRecord::Base
  has_many :studies
end

class Internship < ActiveRecord::Base
  belongs_to :study
  belongs_to :company, :class_name => "Facility", :foreign_key => 'facility_id'
  accepts_nested_attributes_for :company, :study
end

class Facility < ActiveRecord::Base
  has_many :internships
  has_many :locations
  has_many :studies
  accepts_nested_attributes_for :locations
end

class Location < ActiveRecord::Base
  belongs_to :facility
end

Где бы вы поместили :dependent => :destroy и :allow_destroy => true, чтобы включить следующие сценарии?Я не хочу вас смущать.Поэтому я пропускаю свои попытки.

Сценарий стажировки: Пользователь хочет удалить стажировку.

  • Его связанная компания (учреждение) может быть удалена, есликомпания не связана с другой стажировкой.
  • Если это так, местоположения связанной компании могут быть удалены.
  • Соответствующее исследование не будет затронуто.

Сценарий исследования : Пользователь хочет удалить исследование.

  • Его связанный предмет может быть удален, если никакое другое исследование не ссылается на этот предмет.
  • Его связанный предметУниверситет (учреждение) может быть удален, если к этому университету не относится другое исследование.
  • Связанные с ним стажировки могут быть удалены.Компания может быть удалена только в том случае, если на нее не ссылается ни одна другая стажировка.

Я совершенно не уверен, смогу ли я добавить :dependent => :destroy только после has_one и has_many или также после belongs_to.


Редактировать: Чтобы упростить проблему, придерживайтесь следующего (уменьшенного) примера реализации.

class Study < ActiveRecord::Base
  belongs_to :subject
  accepts_nested_attributes_for :subject, :allow_destroy => true
end

class Subject < ActiveRecord::Base
  has_many :studies, :dependent => :destroy
end

На мой взгляд, я предоставляю следующую ссылку.

<%= link_to "Destroy", study, :method => :delete, :confirm => "Are you sure?" %>

Путь основан на именованных маршрутах, заданных конфигурацией отдыха в routes.rb.

resources :studies
resources :subjects

Исследование будет удалено, когда я нажму на ссылку - субъекты останутся нетронутыми.Почему?

Ответы [ 2 ]

2 голосов
/ 14 февраля 2012

Я думаю, что ваши отношения здесь неправильные ...
accepts_nested_attributes_for должен быть объявлен на модели, которая has_many для модели, которой он has_many. Кроме того, в вашем примере уничтожение объекта приведет к dependent_destroy для множества studies, а не наоборот.

1 голос
/ 23 марта 2011

Вы можете добавить :dependent => :destroy ко всем трем, но я не уверен, даст ли это вам достаточно сил, чтобы выполнить необходимые проверки перед определением, должен ли связанный объект быть уничтожен.

У вас есть несколько вариантов.

Добавить обратный вызов before_destroy для каждой модели, которая вызывает исключение или останавливает удаление.

class Facility < ActiveRecord::Base
  has_many :internships
  has_many :locations
  has_many :studies

  def before_destroy
    raise SomethingException if internships.any? || ...
    # or
    errors.add(...
  end
end

или сделайте это молча, переопределив уничтожение

class Facility < ActiveRecord::Base
  has_many :internships
  has_many :locations
  has_many :studies

  def destroy
    return false if internships.any || ...
    super
  end
end

Примечание: это в основном предназначено только для руководства и может быть неправильным способом отмены уничтожения и т. Д. *

...