Как мне убедиться, что атрибут ассоциации правильный для проверки ассоциации? - PullRequest
1 голос
/ 03 марта 2011

У меня есть простой пользователь: ** Отредактировано немного для ясности и по предложению Сэма

class User < ActiveRecord::Base
  # <snip other attribs>
  has_many :handles
  has_one :active_handle, :class_name => "Handle"

  validates_each :active_handle, :allow_nil => true  do |record, attr, value|
    record.errors.add attr, "is not owned by the correct user" unless record.handles.include?(value)
  end
end

И модель ручки:

class Handle < ActiveRecord::Base
  belongs_to :user
  attr_accessible :user_id
  validates :user_id,
        :presence => true,
        :numericality => true

  attr_accessible :name
  validates :name,
        #etc...
end

Теперь я быхотел бы при настройке ассоциации User.active_handle проверить, что дескриптор принадлежит правильному Handle.user_id.Я пытался сделать это в пользовательской валидации, а также в методе валидации в модели User.В обоих случаях он делает полную противоположность того, что я хочу, он устанавливает user_id дескриптора для пользователя, выполняющего проверку.

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

ETA: Я также пытался манипулировать ассоциацией has_one с условиями, которые, похоже, тоже не работают ...

has_one :active_handle,
        :class_name => "Handle",
        :conditions => ['user_id =?', '#{self.id}']

Ответы [ 2 ]

0 голосов
/ 04 марта 2011

Я бы взял другой подход к этой проблеме; двойная ссылка беспорядочная, и, как вы обнаружили, ее трудно поддерживать. Вместо этого я бы поместил активный флаг в модель дескриптора и упорядочил ассоциацию :active_handle для этого флага:

class User < ActiveRecord::Base
    has_many :handles
    has_one  :active_handle, :class_name => 'Handle', :order => 'handles.active DESC'
end

Теперь есть только одна ссылка, и это та же ссылка, которая уже существует для установления простой ассоциации has_many :handles (а именно, атрибут user_id в модели Handle). Поиск активного дескриптора теперь просто вопрос поиска первого дескриптора пользователя с установленным активным флагом. И я бы использовал :order, а не :conditions, поскольку это даст вам хороший запасной вариант: если ни один дескриптор для этого пользователя не имеет активного флага, Rails выберет один для использования по умолчанию.

И тогда, в вашей модели дескриптора, вы можете иметь довольно простую функцию активации:

class Handle < ActiveRecord::Base
    # ...stuff...

    def activate!
        # Pseudocode - sorry!
        sql('UPDATE handles SET active = 0 WHERE user_id = ?', self.user_id)
        self.active = true
        self.save!
    end
end

Или, если вы хотите иметь возможность вызывать что-то вроде user.handles.activate(hdl), вы можете добавить нечто подобное в качестве расширения ассоциации. Или user.active_handle = hdl. Или ...

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

0 голосов
/ 03 марта 2011

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

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

class Handle < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :handles
  validates :handle_can_be_active?

  def handle_can_be_active?
      if self.handles.include?(self.active_handle)
          #no problem
      else
          errors.add_to_base('Must belong to the handle before it can be active!')
      end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...