2014-10-07 29 views
2

我想使用before_save方法将我的模型实例的first_namelast_name转换为大写。当然我可以这样做:在Rails before_save方法中使用多个属性大写

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

但我宁愿一举改变这两个属性。有没有办法在我的模型中选择某些列并将所需的方法应用到他们?

+1

这实际上是在将数据转换为SQL查询之前修改数据。这仍然只包含在一个INSERT/UPDATE语句中 – MrYoshiji 2014-10-07 20:20:38

+0

不知道'downcase'是否大写字符串。你确定你想要做什么? – Surya 2014-10-07 20:21:36

+0

@Surya对不起。修改代码以反映问题 – 2014-10-07 20:22:18

回答

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所有字符串类似的代码,以保持数据的一致性。

+0

有了这个,我得到:'NoMethodError:未定义方法'strip'for nil:NilClass' – 2014-10-07 20:35:24

+1

@CarlEdwards好吧,你提交nil作为值的东西没问题,你可以修复看到更新后的帖子。如果你想我喜欢它,你可以放弃'#strip',因为我不希望用户提交像“John”这样的名字。 '#strip'将在这种情况下删除前导和尾随的空白。 – engineersmnky 2014-10-07 20:37:31

+0

这个结账谢谢!尽管阅读了Ruby文档,但我仍然不清楚“发送”是如何完成的。介意在这种情况下解释它的作用? – 2014-10-07 20:42:44

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 
0

大厦@ engineersmnky的回答进一步为Rails 4+与Concerns(更多here):

应用程序/模型/关注/ 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 
相关问题