Я следовал за скринкастом на rubyonrails.org (создающий блог).
У меня есть следующие модели:
comment.rb
class Comment < ActiveRecord::Base
belongs_to :post
validates_presence_of :body # I added this
end
post.rb
class Post < ActiveRecord::Base
validates_presence_of :body, :title
has_many :comments
end
Отношения между моделями хорошо работают, за исключением одной вещи - когда я удаляю запись сообщения, я ожидал бы, что RoR удалит все связанные записи комментария. Я понимаю, что ActiveRecords является независимой базой данных, таким образом, нет никакого встроенного способа создать внешний ключ, отношения, НА УДАЛЯЮТ, операторы ON UPDATE. Так, есть ли какой-либо способ выполнить это (возможно, сам RoR мог заботиться об удалении связанных комментариев?)?
Да . В ассоциации модели Rails вы можете указать параметр : зависимый
, который может принимать одну из следующих трех форм:
: destroy /: destroy_all
Связанные объекты уничтожаются вместе с этим объектом посредством вызывая их метод destroy
: delete /: delete_all
Все связанные объекты немедленно уничтожаются без вызова их : destroy
method : nullify
Внешние ключи всех связанных объектов устанавливаются на NULL
без вызова их обратных вызовов save
Обратите внимание, что : Параметр зависимой
игнорируется, если у вас настроена ассоциация : has_many X,: through => Y
.
Таким образом, в вашем примере вы можете выбрать, чтобы сообщение удаляло все связанные с ним комментарии, когда само сообщение удаляется без вызова метода destroy
каждого комментария. Это будет выглядеть так:
class Post < ActiveRecord::Base
validates_presence_of :body, :title
has_many :comments, :dependent => :delete_all
end
В Rails 4 вы должны использовать : destroy
вместо : destroy_all
.
Если вы используете : destroy_all
, вы получите исключение:
Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, внешние ключи устанавливаются на
NULL
без вызова их обратных вызововsave
. Обратите внимание, что параметр
: зависимый
игнорируется, если у вас есть: has_many X ,: through => Y
ассоциация установлена.Таким образом, для вашего примера вы можете выбрать, чтобы сообщение удаляло все связанные с ним комментарии при удалении самого сообщения, не вызывая каждый комментарий
destroy
метод. Это будет выглядеть так:class Post < ActiveRecord::Base validates_presence_of :body, :title has_many :comments, :dependent => :delete_all end
Обновление для Rails 4:
В Rails 4 вы должны использовать
: destroy
вместо: destroy_all
.Если вы используете
: destroy_all
, вы получите исключение:Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, внешние ключи устанавливаются на
NULL
без вызова их обратных вызововsave
. Обратите внимание, что параметр
: independent
игнорируется, если у вас есть: has_many X ,: through => Y
ассоциация установлена.Таким образом, для вашего примера вы можете выбрать, чтобы сообщение удаляло все связанные с ним комментарии при удалении самого сообщения, не вызывая каждый комментарий
destroy
метод. Это будет выглядеть так:class Post < ActiveRecord::Base validates_presence_of :body, :title has_many :comments, :dependent => :delete_all end
Обновление для Rails 4:
В Rails 4 вы должны использовать
: destroy
вместо: destroy_all
.Если вы используете
: destroy_all
, вы получите исключение:Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, Параметр зависимой игнорируется, если у вас настроена ассоциация
: has_many X,: through => Y
.Итак, для вашего примера вы можете выбрать, чтобы сообщение удаляло все связанные с ним комментарии, когда само сообщение удаляется без вызова метода
destroy
каждого комментария. Это будет выглядеть так:class Post < ActiveRecord::Base validates_presence_of :body, :title has_many :comments, :dependent => :delete_all end
Обновление для Rails 4:
В Rails 4 вы должны использовать
: destroy
вместо: destroy_all
.Если вы используете
: destroy_all
, вы получите исключение:Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, Параметр зависимой игнорируется, если у вас настроена ассоциация
: has_many X,: through => Y
.Итак, для вашего примера вы можете выбрать, чтобы сообщение удаляло все связанные с ним комментарии, когда само сообщение удаляется без вызова метода
destroy
каждого комментария. Это будет выглядеть так:class Post < ActiveRecord::Base validates_presence_of :body, :title has_many :comments, :dependent => :delete_all end
Обновление для Rails 4:
В Rails 4 вы должны использовать
: destroy
вместо: destroy_all
.Если вы используете
: destroy_all
, вы получите исключение:Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, без вызова метода
destroy
каждого комментария. Это будет выглядеть так:class Post < ActiveRecord::Base validates_presence_of :body, :title has_many :comments, :dependent => :delete_all end
Обновление для Rails 4:
В Rails 4 вы должны использовать
: destroy
вместо: destroy_all
.Если вы используете
: destroy_all
, вы получите исключение:Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, без вызова метода
destroy
каждого комментария. Это будет выглядеть так:class Post < ActiveRecord::Base validates_presence_of :body, :title has_many :comments, :dependent => :delete_all end
Обновление для Rails 4:
В Rails 4 вы должны использовать
: destroy
вместо: destroy_all
.Если вы используете
: destroy_all
, вы получите исключение:Параметр: independent должен быть одним из [: destroy,: delete_all,: nullify, : restrict_with_error,: restrict_with_exception]