Activerecord Rails只更新空字段

Activerecord Rails只更新空字段,activerecord,ruby-on-rails-3.1,Activerecord,Ruby On Rails 3.1,最近在Stackoverflow(我想我是风滚草奖之王)的答案方面运气不太好,但不管怎样: 使用activeRecord时,如何仅更新空字段?我有以下代码: master_info.update_attributes( {:originalTitle => slave_info.originalTitle, :starring => sla

最近在Stackoverflow(我想我是风滚草奖之王)的答案方面运气不太好,但不管怎样:

使用activeRecord时,如何仅更新空字段?我有以下代码:

master_info.update_attributes( {:originalTitle => slave_info.originalTitle,                                                                         
:starring => slave_info.starring,
:theatrical => slave_info.theatrical }
我想要的是:

master_info.update_attributes( {:originalTitle => slave_info.originalTitle, if !master_info.originalTitle.present?                                                                        
:starring => slave_info.starring, if !master_info.starring.present?
:theatrical => slave_info.theatrical if !master_info.theatrical.present? }
master_info.update_attributes( {:originalTitle => slave_info.originalTitle,                                                                         
                          :starring => slave_info.starring,
                          :theatrical => slave_info.theatrical }.reject{ |key, value| value.present?} )
我可以一次做一行,但我尽量避免:

master_info.update_attributes(:originalTitle => slave_info.originalTitle) if !master_info.originalTitle.present?
我读了一些类似于:

master_info.update_attributes( {:originalTitle => slave_info.originalTitle, if !master_info.originalTitle.present?                                                                        
:starring => slave_info.starring, if !master_info.starring.present?
:theatrical => slave_info.theatrical if !master_info.theatrical.present? }
master_info.update_attributes( {:originalTitle => slave_info.originalTitle,                                                                         
                          :starring => slave_info.starring,
                          :theatrical => slave_info.theatrical }.reject{ |key, value| value.present?} )
但这不起作用,它不更新任何内容,甚至不更新空字段

事实上,理想的做法是不必重复字段名,因为它们在master和slave中的名称都是相同的,但我不能在activeRecord上分别进行。但这是第二个问题,主要问题是更新空字段


这里希望这一个不会有风滚草:)

您可以用类似这样的东西覆盖模型中的更新属性

def update_attributes(attributes)
  attributes.each{|attr| attributes.delete(attr) unless read_attribute(attr).empty?}
  super(attributes)
end

我没有测试过这段代码,因此可能需要进行调整。

稍后在这里,但我想我会添加我是如何做到的,以防有人发现它有用

我在第一个答案中使用了该函数,并将其修改为以下内容。正如@ksol在他的评论中所说,您可能希望保持原始的
update\u attributes
方法不变,因此我将此方法添加到了我的模型中。我敢肯定,如果您想在多个模型中使用它,它可以包含在全球范围内

def update_attributes_only_if_blank(attributes)
    attributes.each { |k,v| attributes.delete(k) unless read_attribute(k).blank? }
    update_attributes(attributes)
end

这将从哈希中删除任何属性,除非它已经有值。然后,它会正常更新其余的属性。

如果您想保持原来的更新方式,您应该定义另一种方法,而不是重载。对不起,我不明白。如果接收端的属性为空,我想更新这些属性。这段代码似乎从传入字段中删除了空属性。还是我读错了?对不起,我改为
,除非读取属性(attr).empty?
。费尔南多,我还是有点迷路。你能解释一下代码是如何确保我正确阅读的吗?就我个人而言,我不太喜欢重写ActiveRecord持久性方法。这些方法具有已知的行为,并且是Rails约定的一部分。实现自己版本的方法并使用它更容易。这样,当其他人出现在您的代码中时,他们不会得到任何令人讨厌的惊喜。