0

У меня есть FormObject для регистрации, которая создает пользователь и много модели для него внутри create метода.Отключить автоинкремент идентификатора внутри ActiveRecord :: Base.transaction

def create 
    ActiveRecord::Base.transaction do 
    @user = User.create(@params[:user]) 
    process_bonuses_for_user 
    process_actions_for_user 
    # et.c., giant amount of methods 
    end 

    @user.persisted? # to return the true of false to controller 
end 

я встретил странное поведение моего FormObject. Даже он успешно прошел (создайте много моделей) или неудачно (не сохраняя их), модель id модели User является автоинкрементной. Таким образом, каждый пытается сохранить что-то, используя мой FormObject, увеличит значение следующего id для пользователя. Это нормальная ситуация, когда User создан успешно, но не нормально, когда пользователь делает ошибку в регистрационной форме.

Как я могу отключить это непредсказуемое поведение?

P.S. Я знаю, что все работает, когда я пишу @user = User.new(@params[:user]) в начале create и @user.save в конце, но есть много ассоциаций, и я не хочу писать много autosave или inverse_of в моих моделях.

P.P.S. Я postgresql-9.4 пользователь

ответ

0

Ваша сделка не работает, так как вы используете create. Вам нужно использовать версию bang (create!), чтобы вызвать исключение при сбое, которое вызывает откат. Обратите внимание, что вам понадобится rescue исключение InvalidRecord.

+0

Хм ... Похоже, избыточна – asiniy

+0

Это единственный способ убедиться, что ваш 'transaction' работает. :) – fylooi

0

На мой взгляд, это может быть что-то вроде этого:

def create 
    @user = User.new(params[:user]) 

    respond_to do |format| 
     if @user.save 
     process_bonuses_for_user 
     process_actions_for_user 
     # et.c., giant amount of methods 
     ... 
     format.html { redirect_to ... } 
     end 
    end 
+0

Неправильно. Что будет, если пользователь действителен, но метод 'process_actions_for_user' не прошел? – asiniy

+0

Итак, если 'process_actions_for_user' связан с' User Model', он должен быть помещен в область проверки. Если это связано с другими моделями, пользователь должен быть закрыт перед ним. Да? Другой случай - вы можете использовать before_action: and after_action: filters ... –

+0

В этом случае есть объекты формы ... – asiniy