2015-08-10 1 views
3

В основном у меня есть приложение (с использованием программы), где пользователь подписывает registrations#new с помощью только электронной почты и пароля; это регистрирует и создает пользователя. Он немедленно возвращает их в registrations#edit, где они вводят остальную информацию.Имена контроллеров FriendlyID проверяют вопрос включения

Я использую атрибут :name с friendly_id для тщеславия. Этот атрибут имеет 3 требования:

  1. Он должен быть написан один раз, но неизменен после его написания.
  2. Это не может быть ни один из имен контроллера (или он сломает приложение).
  3. Это уникальный

Для # 2 Поэтому я добавил следующую проверку моей модели: `

validates :name, :exclusion => { :in => %w(
    admin cars registrations users 
), :message => "Sorry \"%{value}\" is taken!"}` 

Для # 3 я добавил validates_uniqueness_of :name

Для # 1 У меня есть следующее, на мой взгляд, под регистрацией # edit:

<% if @user.name.blank?%> 
       <br> 
       <h2>Choose your username</h2> 

        <%= f.input :name, :value => "Username" , required: true, autofocus: true, label:false, class: 'usernameinputc' %> 

<br> 

Это эффективно скрывает его от пользователя, если он не существует. Проблема, с которой я столкнулась, заключается в том, что если они вводят имя контроллера в качестве своего :name или что-то уже сделанное, оно даст ошибку разработки и отправит их обратно, но поле будет скрыто. Если я удалю условие, то он позволяет им изменять их :name, даже если это было действительно? Как я могу сделать это, чтобы он показывал, только если атрибут имени не был сохранен?

Примечания: Я попытался if @user.name.persisted? он не дал мне нет ошибки методы для nilClass (я думаю, потому что :name не существует

UPDATE

Так что я пытался добавить его в качестве виртуального атрибута, я. добавил поле:.. имя пользователя для моего разрешенного Params в качестве виртуального атрибута Имея немного неприятностей с методами получения и установок я попытался это:

def username 
    self.name if self.name.persisted? 
end 

я все еще получаю ошибку нет методы

.
+0

В вашем обновлении duh, потому что вы вызываете '#persisted?' На нулевом значении! '#persisted?' - это метод ActiveRecord, а не String! Это не то, что вы хотите делать в любом случае, потому что вы хотите сохранить '.name' отдельно от' .username', пока вы окончательно не сохраните. – Chloe

+0

Как я уже сказал, я никогда не использовал виртуальные атрибуты, прежде чем вы могли бы написать мне пример? Мои ответы на переполнение стека обычно выглядят так: http://stackoverflow.com/questions/31822006/rails-4-displaying-a-dependent-model-in-a-table/31825679#31825679 – ChiefRockaChris

ответ

1

Что делать, если вы попытаетесь это сделать? Это подтвердит ваше имя против черного списка, но также будет указывать user.name на пустое, когда это произойдет. Таким образом, ваш erb будет отображаться правильно.

validate do |user| 
    if %w(admin cars registrations users).include?(user.name) 

     user.errors[:name] << "Sorry \"" + user.name + "\" is taken!" 
     user.name = "" 
    end 
    end 
+1

Это сработало! Спасибо за пример! – ChiefRockaChris

-2

Используйте виртуальный атрибут для хранения значения в форме.

attr_accessor :desired_name 

Когда форма отправлена, User.desired_name будет заполнена. Затем выполнить свои валидаций по значению. Если он пройдет, скопируйте виртуальный атрибут в атрибут поля базы данных и сохраните и перенаправьте. (Или скопируйте значение, подтвердите, и если произошла ошибка, установите .name обратно на нуль.) Если реальное поле не пусто, скройте форму.

Вы должны знать, что это почти угроза безопасности, чтобы скрыть форму. Вы должны подтвердить в своем методе #update, что уже нет существующего значения для .name, поскольку хакер может создать свою собственную форму и передать значение для ее изменения.

Вот учебник виртуальных атрибутов: http://railscasts.com/episodes/16-virtual-attributes

+1

Я никогда не использовал виртуальный атрибут, не могли бы вы привести мне пример того, как я это сделаю? – ChiefRockaChris

+0

@ChiefrockaChris Обновлено. – Chloe

+0

@ChiefRockaChris 'attr_accessor' является частью языка Ruby и определенно НЕ устарел –

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