ActiveRecord # save_only_valid_attributes - PullRequest
       12

ActiveRecord # save_only_valid_attributes

0 голосов
/ 17 сентября 2008

Я ищу вариант метода #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.

Ответы [ 2 ]

0 голосов
/ 14 апреля 2010

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

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

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

0 голосов
/ 18 сентября 2008

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

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

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

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

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...