Я унаследовал приложение Rails с проблемой: создание пользователя откатывается, если не удается отправить приветственное письмо. (Но мы всегда хотим, чтобы пользователь был создан).
create вызывает метод new , затем save , и шаг электронной почты вызывается в after_create , поэтому проблема с электронной почтой не должна не влияет на сохранение, верно?
Но в соответствии с трассировкой стека мы терпим неудачу в:
- send_email метод ( delivery_now строка). Этот метод был вызван:
- метод create в users_controller (строка if @ user.save )
Примечание: единственное место в коде, которое вызывается send_email , находится в user.rb:
after_create :send_email
И, конечно, мы ожидаем, что транзакция будет отменена, если какой-либо из обратных вызовов 'before' вернет false, но есть только два, которые просто обновляют данные объекта и кажутся не связанными с отправкой по электронной почте:
before_save :combine_dates
before_save :set_timestamps
См. Ниже два метода, которые терпят неудачу, а затем два метода «до», которые кажутся несвязанными. Интересно, что когда я ломаю электронную почту, чтобы она не отправлялась, мы не регистрируем ни одну из этих строк logger.error в CAPS - означает ли это, что @ user.save дает сбой так, как мы не можем восстановить?
Вот метод создания:
def create
@user = User.new(user_params_with_races)
existing_user = User.find_by_email(@user.email)
if existing_user
@user.is_dupe = true
end
if @user.save
Rails.logger.error "USER.SAVE WAS TRUE"
respond_to do |format|
format.html do
if @user.contact?
redirect_to mailing_list_user_path(@user)
return
end
redirect_to edit_user_path(@user), notice: 'User was successfully created.'
end
format.js do
if @user.contact?
render json: {redirect: mailing_list_user_path(@user)}
else
render json: {action: user_path(@user), email: @user.email}
end
end
end
else
Rails.logger.error "USER.SAVE WAS FALSE"
respond_to do |format|
format.html { render :new }
format.js { head :not_acceptable }
end
end
end
Вот send_email:
def send_email
UserMailer.mailing_list(self).deliver_now if contact?
UserMailer.welcome(self).deliver_now if diagnosed?
end
Вот два метода «до»:
def set_timestamps
if email == email_confirmation and registered_at.blank?
self.registered_at = Time.new
end
end
def combine_dates
if birthday_year_year.present? && birthday_day.present? && birthday_month.present?
begin
self.send('birthday=', Date.new(birthday_year_year.to_i, birthday_month.to_i, birthday_day.to_i))
rescue
self.send('birthday=', nil)
end
end
if bd_birthday_year.present? && bd_birthday_day.present? && bd_birthday_month.present?
begin
self.send('bd_birthday=', Date.new(bd_birthday_year.to_i, bd_birthday_month.to_i, bd_birthday_day.to_i))
rescue
self.send('bd_birthday=', nil)
end
end
end