2016-02-03 3 views
0

Например, если я бег test.update_attributes prop1: 'test', prop2: 'test2' когда prop1 и prop2 имеют валидации, которые мешают эти ценности, test.prop1 все равно будут 'test' и test.prop2 все равно будет 'test2'. Почему это происходит и как я могу это исправить?update_attributes изменения атрибутов, даже если проверка не пройдена

ответ

1

Согласно the Rails docs for update_attributes, это псевдоним update. Его источник выглядит следующим образом:

# File activerecord/lib/active_record/persistence.rb, line 247 
def update(attributes) 
    # The following transaction covers any possible database side-effects of the 
    # attributes assignment. For example, setting the IDs of a child collection. 
    with_transaction_returning_status do 
    assign_attributes(attributes) 
    save 
    end 
end 

Таким образом, он завернут транзакцию DB, поэтому происходит откат. Однако давайте посмотрим assign_attributes. По its source:

# File activerecord/lib/active_record/attribute_assignment.rb, line 23 
def assign_attributes(new_attributes) 
    ... 
    _assign_attribute(k, v) 
    ... 
end 

Это is defined as:

# File activerecord/lib/active_record/attribute_assignment.rb, line 53 
def _assign_attribute(k, v) 
    public_send("#{k}=", v) 
rescue NoMethodError 
    if respond_to?("#{k}=") 
    raise 
    else 
    raise UnknownAttributeError.new(self, k) 
    end 
end 

Так что, когда вы звоните test.update_attributes prop1: 'test', prop2: 'test', это в основном сводится к:

test.prop1 = 'test' 
test.prop2 = 'test' 
test.save 

Если save проваливает валидации, наши входы копия памяти test по-прежнему имеет модифицированные prop1 и prop2 значений. Следовательно, нам нужно использовать test.reload, и проблема решена (т. Е. Наши версии БД и в памяти не изменяются).

tl; dr Использовать test.reload после неудачного вызова update_attributes.

0

Попробуйте окружив его Условный оператор:

if test.update(test_params) 
    # your code here 
else 
    # your code here 
end 
+0

Когда я пытаюсь это, 'test' все еще имеет те же проблемы после' if' заявления. – BalinKingOfMoria

+0

Операции 'if' не всегда возможны; например, 'test.update!' все равно будут вызывать те же проблемы. – BalinKingOfMoria