Как установить постоянные переменные экземпляра для объектов ActiveRecord без карты идентичности? - PullRequest
1 голос
/ 04 августа 2011

Я долго стучал головой о проблему, пока не понял, что происходит.

Я хочу создать комитет, в котором всегда должен быть хотя бы один член.Чтобы достичь этого, каждый участник проверяет, что это не последний член перед уничтожением.

Приведенный ниже код должен предотвращать уничтожение последнего члена, ЕСЛИ сам комитет не уничтожается, и в этом случае он самоуничтожается.

class Committee < ActiveRecord::Base

  has_many :committee_members
  before_destroy: { @destroy_initiated = true }

  def destroy_initiated?
    @destroy_initiated
  end

end

class CommitteeMember < ActiveRecord::Base

  belongs_to :committee
  before_destroy :ensure_not_last

  def ensure_not_last
    unless self.committee.destroy_initiated?
      if self.committee.committee_members.count == 1
        raise 'You cannot remove the last committe member. Try destroying the committee instead'
      end
    end
  end

end

Проблема

Проблема в том, что каждый CommitteeMember ссылается на отдельный экземпляр объекта Committee, все они имеют разные идентификаторы объектов:

например#<Committee:0x00000105c41f20> v. #<Committee:0x00000105c2c3a0>

Это означает, что даже когда я устанавливаю значение @destroy_initiated в значение true для одного экземпляра комитета с идентификатором 20, оно не будет установлено в значение true в экземпляре, на который ссылается один изее Committee_members.

Оставляя в стороне Rails 3.1, который, как я знаю, имеет карту идентичности, есть ли чистый обходной путь к наличию переменной экземпляра, которая доступна во всех экземплярах комитета?

Я рассматриваю вопрос о создании переменной класса, содержащей карту destroy_initiated?к каждому идентификатору комитета, но это выглядит довольно грязно.

1 Ответ

0 голосов
/ 04 августа 2011

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

В приложении, которое я только недавно запустил в производство, мы бы по существу кэшировали объект как переменную экземпляра в ApplicationController. Затем, когда бы нам это ни понадобилось, мы просто запрашиваем переменную экземпляра, а не находим ее с помощью Active Record.

class ApplicationController < ActionController::Base
  before_filter :set_committee

  def set_committee
    @committee ||= Committee.new()
  end
end

Так что теперь, во время запроса, все, что унаследовано от ApplicationController, может получить доступ к объекту @committee. Если вы можете использовать подобный шаблон (не обязательно должен быть контроллером приложения, может быть просто любым другим контроллером), у вас по сути будет «глобальная» переменная на время запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...