2009-06-18 3 views
4

У меня есть модель с именем Profile, которая принадлежит пользователю, поэтому для отслеживания базы данных есть «user_id». В локальном интерфейсе администратора, который я сделал для этой модели, я хотел предоставить гибкость, позволяющую администратору вводить имя пользователя в поле на экране редактирования, а затем разрешать это пользователю_id для сохранения в контроллере.Как проверить, что ассоциация действительна

Однако вопрос в том, как я могу проверить, что имя пользователя имеет действительный возврат? Я обнаружил, что в ActiveRecord :: Validation нет метода проверки существования ассоциации. Как вы справитесь с такой ситуацией?

Обновление: что я хочу сделать, это проверить, что поле имени пользователя в форме действительно является реальным пользователем, после чего я могу сохранить этот user_id обратно в редактируемый администратором профиль. Здесь «return» означает возвращаемый объект пользователя.

ответ

5

Эта проблема является хорошим кандидатом на виртуальные атрибуты. Вместо того, чтобы пытаться разрешить имя пользователя, пусть модель профиля подходит для вас.

class Profile 

    belongs_to :user 

    # ... 

    def username 
    user.try(:username) 
    end 

    def username=(value) 
    self.user = User.find_by_username(value) 
    end 

end 

Затем в форме

<% form_for @profile do |f| %> 

    <%= f.text_field :username %> 

<% end %> 

Когда представляется, значение для поля имени пользователя автоматически передается со всеми другими атрибутами реального ActiveRecord. ActiveRecord будет искать имя пользователя = setter и будет разрешать связь. Если ассоциация возвращает nil (никакой записи не существует с заданным именем пользователя), тогда она установит текущий user_id на нуль, и проверка будет сбой, как ожидалось.

Возможно, вы захотите настроить код ошибки, чтобы сделать более значимым.

EDIT: Добавлен пример.

validate :ensure_username_exists 

def username=(value) 
    self.user_id = User.find_by_username(value) || 0 
end 

protected 

    def ensure_username_exists 
    if user_id == 0 # nil is allowed 
     errors.add(:user_id, "Username doesn't exists") 
     return false 
    end 
    end 
+0

Как насчет того, является ли user_id необязательным? Который здесь профиль не может принадлежать никому. – itsnotvalid

+0

Существует много способов сделать это. Возможно, вы захотите изменить имя пользователя =(), чтобы вернуть 0, если имя пользователя не существует, а не nil. В этом случае вы можете проверить, сохраняет ли значение == 0 и делает недействительным объект. validate: secure_username_exists def username = (значение) self.user_id = User.find_by_username (value) || 0 конец защищен Защиту ensure_username_exists если user_id == 0 # ноль допускается ошибки.add (: user_id, «Имя пользователя не существует») return false конец конец Это всего лишь одно возможное решение. –

+0

Извините. Я написал пример, но кажется, что комментарии не могут содержать код. : S –

1

Это полезный справочник для активных ассоциаций Записи: http://guides.rubyonrails.org/association_basics.html

Для проверки существования ассоциации, просто проверить ассоциации .nil?

if @profile.user.nil? 
    ... something ... 
end 

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

+0

Обновлено. Благодарю. – itsnotvalid

+0

Считается плохой практикой проверять значение для nil ?. Используйте вместо этого. Таким образом, ваш пример выше: if @ profile.user; ..что нибудь; end – karlingen

Смежные вопросы