Вопрос

Я ищу вариацию на тему #save Метод, который сохранит только атрибуты, которые не имеют прикрепленных к ним ошибок.Таким образом, модель может быть обновлена ​​без действий в целом, и это все равно предотвратит сохранение неверных данных в базе данных.

Под «действительными атрибутами» я подразумеваю те атрибуты, которые дают ноль при вызове @model_instance.errors.on(:attribute)

У кого-нибудь есть идеи, как это сделать?

На данный момент у меня есть следующее:

def save_valid_attributes 
 valid? 
 update_atrtibutes attributes.inject({}){|k, v, m| m[k] = v unless errors_on(k.to_sym); m} 
end 

Это работает, если при назначении не выполняется обработка, что в моем случае есть.Например, у меня есть столбец базы данных «start_date» и определены два метода:

def nice_start_date=(startdate)
 self.start_date = Chronic.parse(startdate) || startdate
end

def nice_start_date
 self.start_date.to_s
end

Эти два метода позволяют мне правильно анализировать введенные пользователем даты с помощью Chronic перед сохранением.Итак, второй способ сделать это, по одному атрибуту за раз:

def save_valid_attributes(attrib) 
  valid?
  attrib.each{|(k,v)| send("${k}=", v); save; reload)
end

Модель необходимо перезагружать каждый раз, поскольку, если одна из дат недействительна и не сохраняется, это не позволит сохранить все дальнейшие атрибуты.

Есть лучший способ сделать это?Я уверен, что это не редкая проблема в мире Rails, я просто не могу найти ничего во вселенной знаний Google.

Это было полезно?

Решение

Я не уверен, насколько вам повезет с этим, если вы не будете много возиться.

Независимо от того, насколько СУХОЙ, ОО и простой ваша структура делает вещи (а в данном случае - много =), вы все равно должны помнить, что она работает перед стандартной реляционной базой данных, в которой есть атомарные фиксации в качестве одной из ее функций. определение функции.Он разработан с нуля, чтобы гарантировать, что либо все ваши изменения будут зафиксированы, либо ни одного.

Фактически вы преодолеете эту стандартную функциональность с помощью чего-то, что на 100% противоречит тому, как был разработан Rail +.Это, скорее всего, приведет (как уже говорилось) к противоречивым данным.

Было сказано, что ...это всегда возможно.Я бы посмотрел на ручную проверку нужных вам атрибутов, а затем использовал встроенный метод. object.update_attribute_with_validation_skipping.

Удачи!

Другие советы

Вы можете перезаписать #save так:

def save
  errors.each do |attr, msg|
    send("#{attr}=", send("#{attr}_was"))
  end
  super
end

Это приведет к сбросу всех атрибутов с ошибками, привязанными к их исходному значению.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top