Ruby on rails 在保存方法之前将Rails中的多个属性大写

Ruby on rails 在保存方法之前将Rails中的多个属性大写,ruby-on-rails,ruby,callback,rails-activerecord,models,Ruby On Rails,Ruby,Callback,Rails Activerecord,Models,我想使用before_save方法将模型实例的名字和姓氏大写。我当然可以这样做: before_save do self.first_name = first_name.capitalize self.last_name = last_name.capitalize end 但我更愿意一下子改变这两个属性。有没有办法在我的模型中选择某些列并对其应用所需的方法?您可以这样做 before_save :capitalize_attributes private def capit

我想使用before_save方法将模型实例的名字和姓氏大写。我当然可以这样做:

before_save do 
  self.first_name = first_name.capitalize
  self.last_name = last_name.capitalize
end

但我更愿意一下子改变这两个属性。有没有办法在我的模型中选择某些列并对其应用所需的方法?

您可以这样做

before_save :capitalize_attributes

private
   def capitalize_attributes
     capitalizable = ["first_name","last_name"]
     self.attributes.each do |attr,val|
       #based on comment either of these will work
       #if you want to store nil in the DB then
       self.send("#{attr}=",val.strip.capitalize) if capitalizable.include?(attr) && !val.nil?
       #if you want to store a blank string in the DB then 
        self.send("#{attr}=",val.to_s.strip.capitalize) if capitalizable.include?(attr)
     end
   end

然后,只需将要大写的属性添加到大写数组中即可。我使用类似的代码升级某些模型中的所有字符串,只是为了保持数据的一致性。

这只是@engieeringmnky答案的另一个版本:

before_save :capitalize_attributes

private
   def capitalize_attributes
     self.attributes.select{ |a| ["first_name","last_name"].include? a }.each do |attr, val|
       self.send("#{attr}=", val.try(:strip).try(:capitalize))
     end
   end

基于@engineersmnky对Rails 4+的进一步回答,包括:

app/models/concerns/model_.rb

module ModelHooks
  extend ActiveSupport::Concern

  included do
    before_save :capitalize_attributes
  end

  def capitalize_attributes
     self.attributes.each do |attr,val|
       # if the attribute only has spaces, then this will store nil in the DB
       self.send("#{attr}=",val.strip.capitalize) if self.capitalizable_attrs.include?(attr) && !val.nil?
     end    
  end
end
然后在您的模型中:

class Trail < ApplicationRecord
  include ModelHooks

  def capitalizable_attrs
    ["name"] # return an array of attributes you want to capitalize
  end

end

这实际上是在将数据转换为SQL查询之前对其进行修改。这仍然只包含在一个INSERT/UPDATE语句中。不确定downcase是否将字符串大写。“你确定你想做什么吗?”苏里亚对此表示抱歉。修订守则以反映question@MrYoshiji对的与其说是查询数据库,不如说是因为缺少更好的术语,选择模型中所需的列并应用大写方法。但最终您必须编写这些列名,对吗?为什么你认为这不是你想要的方式?通过这个我得到:NoMethodError:nil的未定义方法'strip':NilClass@CarlEdwards好的,所以你提交了nil作为一个值,你可以修改它,看看更新后的帖子。如果你愿意的话,你可以把这条脱衣舞扔掉。我喜欢它,因为我不希望用户提交像约翰这样的名字。在这种情况下,strip将删除前导和尾随空格。这将签出,谢谢!尽管阅读了Ruby文档,我还是有点不清楚send实现了什么。请您解释一下它在这种情况下的作用好吗?@CarlEdwards简单地说,send允许您在对象上调用一个方法,而无需特别写出该方法,因此这实际上是调用first_name=val.strip.capitalize和last_name=val.strip.capitalize。这本质上就是调用每个方法的方式,尽管有些方法根据调用它的范围使用public_send。若要获得更深入的解释,而这些解释不适合发表在评论中,只需谷歌一下send在ruby中的作用。非常感谢您的帮助