Ruby on rails 在保存方法之前将Rails中的多个属性大写
我想使用before_save方法将模型实例的名字和姓氏大写。我当然可以这样做: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 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中的作用。非常感谢您的帮助