Поддерживать ассоциации с act_as_paranoid
У меня есть две модели, одна из которых - пользователь, а другая - комментарии. Комментарии принадлежат Пользователю.
class User < ActiveRecord::Base
act_as_paranoid
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
end
Когда я выполняю user.delete в моем контроллере, я получаю ожидаемый результат от установленного столбца delete_at и скрытой записи.
Моя проблема заключается в том, что ассоциации комментариев для пользователя установлены в нуль. Так что теперь на сайте нет ни одного пользователя, владеющего комментарием. Мне бы хотелось, чтобы в комментарии все еще отображалось имя пользователя, а не "Нет", "Аноним" и т. Д.
Глядя на источник на github https://github.com/goncalossilva/rails3_acts_as_paranoid/blob/rails3.2/lib/acts_as_paranoid/core.rb кажется, что он вызывает run_callbacks, что, в свою очередь, приводит к тому, что Rails 3 возвращается к значению по умолчанию Nullify для ассоциаций,
В моем случае я просто хочу закрыть учетную запись пользователя при удалении. Больше не показывается в запросах, так что Authlogic будет отказывать им, а страница индекса пользователя не будет их показывать. Но, тем не менее, разрешается владеть всем, что принадлежит пользователю, (поскольку они могут вернуться и т. Д.).
Есть ли лучший способ сделать это, тогда действует___параноид?
1 ответ
Вместо того, чтобы переопределить метод уничтожения, я создал метод close, который просто устанавливает closed_at в отметку времени. Если вы установите область по умолчанию что-то вроде:
default_scope { where("closed_at IS NULL") }
Тогда модель не будет отображаться ни для каких запросов, включая User.All. Вы можете удалить область, чтобы получить полный запрос, по сути, я взял эти идеи из act_as_paranoid, но гораздо проще. Проблема в том, что тогда, хотя в Комментариях по-прежнему установлен user_id, область по умолчанию запускается с любой загрузкой ассоциации. Так сказать
c = Comment.first
c.user
Это выведет ноль, если user_id - закрытая учетная запись. В моем случае самым простым решением было удалить область видимости по умолчанию и изменить мою функцию Authlogic следующим образом:
def self.find_by_username_or_email(login)
u = User.find(:first, :conditions => ["lower(username) = ?", login.downcase]) || User.find_by_email(login)
return u unless u.closed_at
end
Таким образом, закрытые учетные записи не могут войти. Везде, где я перечисляю пользователей в своих представлениях, я использовал скрытую область видимости.
Не уверен, что это было самое лучшее и элегантное решение. Но для моих целей это работает.