Ответ 1
вы должны перезаписать автора атрибута:
class User < ActiveRecord::Base
def username=(val)
write_attribute(:username, val.downcase)
end
end
Быстрый пример: пользователь вводит имя пользователя в форму, и мне нужно сделать это имя пользователя перед сохранением его в базе данных приложения, тем самым сделав его надолго строчным.
Где бы я поместил этот код и как мне получить доступ к данным, которые будут внизу?
Спасибо.
вы должны перезаписать автора атрибута:
class User < ActiveRecord::Base
def username=(val)
write_attribute(:username, val.downcase)
end
end
Вы можете использовать один из обратных вызовов ActiveRecords в своей модели пользователя, например, что-то вроде этого:
before_save { |user| user.username = user.username.downcase }
В вашей модели пользователя (models/user.rb) воспользуйтесь обратными вызовами ActiveRecord:
before_save do
self.username = self.username.downcase
end
Я потратил некоторое время на поиск ошибки, которая мешала мне использовать этот код. Моя база данных откатывалась каждый раз, когда я пытался перехватить атрибут и изменил его на false
перед сохранением.
Я вношу свой ответ здесь, потому что этот поток был первым результатом Google для выполнения этой задачи, но не охватывал всю возвращаемую проблему false
.
Если какой-либо из ваших обратных вызовов возвращает false
, все будет откат в db.
Я пытался установить Предложение, которое будет создано, чтобы оно не принималось в базе данных или @offer.accepted = false
. Проблема заключалась в том, что эта строка заставляла весь метод возвращать false и откатывать весь процесс.
Я исправил его, вставив в неявный возврат true
впоследствии
Код, который работал:
before_save {|offer| offer.accepted = false; true}
Takeaway: ваши обратные вызовы не могут вернуть false
, если вы хотите, чтобы они преуспели.
Источник: rails 3: Мне нужно дать true true в обратном вызове before_save для объекта .save для работы?
def username=(str)
super(str.downcase)
end
Я подумал, что это намного проще.
В общем случае кнопка "Отправить" в форме должна делегировать действие контроллера где имеются параметры [: имя_пользователя]. Вы можете ввести SomeModel.update(params) или create (params).
Итак, вы можете сделать это в действии контроллера.
Я бы предложил добавить Observer в модель и выполнить это действие в методе before_save. Тогда гарантируется, что нижнее регистрационное имя пользователя не зависит от того, какой контроллер или действие его создает, и если есть проблема с выполнением каких-либо действий в наблюдателе, генерируется исключение, и объект не будет сохраняться.
Изменить: Обратите внимание, что не может делать Model.save в пределах before_save, привязанных к этой модели, иначе вы окажетесь в бесконечном цикле. Вам нужно будет сделать update_attributes или что-то еще.