ActiveRecord#save_only_valid_attributes
时间:2020-03-05 18:57:53 来源:igfitidea点击:
我正在寻找只会保存的#save方法的变体
没有添加错误的属性。
因此,可以在不整体有效的情况下更新模型,这将
仍然可以防止将无效数据保存到数据库。
"有效属性"是指那些在调用@ model_instance.errors.on(:attribute)时给出nil的属性
任何人都有一个如何实现此目标的想法?
到目前为止,我有以下内容:
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
这两种方法使我可以在保存之前使用"慢性"正确解析用户输入的日期。因此,第二种方法是一次设置一个属性:
def save_valid_attributes(attrib) valid? attrib.each{|(k,v)| send("${k}=", v); save; reload) end
每次都需要重新加载模型,因为如果其中一个日期无效且不保存,则它将阻止保存所有其他属性。
有一个更好的方法吗?我敢肯定,这在Rails界不是一个普遍的问题,我似乎在Google知识领域中找不到任何东西。
解决方案
回答
我不确定在没有太多混乱的情况下我们将获得多少运气。
不管DRY和OO如何轻松实现框架(在这种情况下,很多情况下=),我们都必须记住它运行在沼泽标准关系数据库的前面,该数据库具有原子提交,这是其定义功能之一。它是从头开始设计的,以确保所有更改都已提交或者不提交。
实际上,我们将过度使用此标准功能,而与Rails +的设计工作原理大相径庭。如前所述,这很可能导致数据不一致。
话说回来 。 。 。总是有可能的。我会仔细检查一下我们关心的属性,然后使用内置方法" object.update_attribute_with_validation_skipping"。
祝你好运!
回答
我们可以像这样覆盖#save
:
def save errors.each do |attr, msg| send("#{attr}=", send("#{attr}_was")) end super end
这将重置所有属性,并在其原始值上添加错误。