2016-07-28 1 views
2

Rails представил этот синтаксис throw(:abort), но теперь, как мне получить значимые ошибки уничтожения?Rails 5 throw abort: как настроить сообщения об ошибках?

Для проверки ошибок можно было бы сделать

if not user.save 
    # => user.errors has information 

if not user.destroy 
    # => user.errors is empty 

Вот моя модель

class User 

    before_destroy :destroy_validation, 
    if: :some_reason 

    private 

    def destroy_validation 
    throw(:abort) if some_condition 
    end 

ответ

11

Вы можете использовать errors.add для метода класса.

модель Пользователь:

def destroy_validation 
    if some_condition 
    errors.add(:base, "can't be destroyed cause x,y or z") 
    throw(:abort) 
    end 
end 

контроллер Пользователи:

def destroy 
    if @user.destroy 
    respond_to do |format| 
     format.html { redirect_to users_path, notice: ':)' } 
     format.json { head :no_content } 
    end 
    else 
    respond_to do |format| 
     format.html { redirect_to users_path, alert: ":(#{@user.errors[:base]}"} 
    end 
    end 
end 
1

Gonzalo S answer это прекрасно. Howerver, если вы хотите немного более чистый код, вы можете рассмотреть вспомогательный метод. Следующий код работает лучше всего в Rails 5.0 или выше, поскольку вы можете использовать модель ApplicationRecord.

class ApplicationRecord < ActiveRecord::Base 
    self.abstract_class = true 

private 

    def halt(tag: :abort, attr: :base, msg: nil) 
    errors.add(attr, msg) if msg 
    throw(tag) 
    end 

end 

Теперь вы можете сделать:

class User < ApplicationRecord 

    before_destroy(if: :condition) { halt msg: 'Your message.' } 

    # or if you have some longer condition: 
    before_destroy if: -> { condition1 && condition2 && condition3 } do 
    halt msg: 'Your message.' 
    end 

    # or more in lines with your example: 
    before_destroy :destroy_validation, if: :some_reason 

private 

    def destroy_validation 
    halt msg: 'Your message.' if some_condition 
    end 

end