编写before_save函数以检查所有目标属性不是空白的更好​​方法?

时间:2013-08-29 06:41:57

标签: ruby-on-rails activerecord ruby-on-rails-3.2

在我的项目中,我有一个有四个属性的模型:名称,描述,内容和完成。

我想检查除保存之前是否空白的所有属性。如果不为空,则将completed设置为1,否则设置为0。

我使用ActiveRecord和Mysql,因此它也会有id,created_at和updated_at列。

我写了一个像这样的before_save回调:

def check_completed
  if self.attributes.except("id", "created_at", "updated_at").all? {|k, v| v.present?}
    self.completed = 1
  else
    self.completed = 0
  end
end

它有效,但看起来很难看。我想删除except函数调用。

有没有更好的方法呢?

2 个答案:

答案 0 :(得分:0)

我建议不要依赖self.attributes,因为您可能希望将来为模型添加其他属性。如果是这样,您必须在except列表中添加新属性。

相反,你可以这样做:

self.completed = %w(name description content).all? { |attr| !send(attr).blank? } ? 1 : 0

答案 1 :(得分:0)

我假设使用了.except方法,因为id,created_at和updated_at都是由MySQL内部生成和管理的。因此,该列表扩展或更改将是不寻常的。我同意代码是好的提供。如果你想缩短它,你可以使用三元组:

def check_completed
  self.attributes.except("id", "created_at", "updated_at").all? {|k, v| v.present?} ? 1 : 0
end

消除.except方法会让您在模型更改时随时都可以管理此方法。

扩展此讨论: 我很想知道你想要回归1或0?没有看到更多的代码,我不确定你的意图。但是,如果“before”回调返回false,则停止执行并回滚事务。在任何其他情况下,继续执行。在Ruby中,0不是假的。 False只能由false或nil触发。我的期望是,更有可能使用true代替1而false代替0?如果是这样,代码将是:

def check_completed
  self.attributes.except("id", "created_at", "updated_at").all? {|k, v| v.present?} ? true : false
end

如果没有任何用户属性,则会取消并回滚该事务。但是,这取决于你。