我想使用first_name
方法将我的模型实例的last_name
和before_save
大写。我当然可以这样做:
before_save do
self.first_name = first_name.capitalize
self.last_name = last_name.capitalize
end
但我更倾向于一举改变这两个属性。有没有办法在我的模型中选择某些列并将所需的方法应用于它们?
答案 0 :(得分:3)
你可以做这样的事情
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
然后,您只需将要大写的属性添加到capitalizable
数组即可。我在某些模型中对upcase
所有字符串使用类似的代码,只是为了保持数据的一致性。
答案 1 :(得分:0)
这只是@ 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
答案 2 :(得分:0)
在@ engineersmnky的基础上,通过Concerns(更多here)进一步回答Rails 4+:
应用程序/模型/关切/ model_hooks.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