2009-05-19 84 views
3

我试图从模型中的字段中删除逗号。我希望用户输入一个数字,即10,000,并且该数字应该作为10000存储在数据库中。我希望我可以做一些模型端规范化来删除逗号。我不想依赖视图或控制器来正确格式化数据。Rails/ActiveRecord:字段标准化

我想:

before_validation :normalize 

def normalize 
self['thenumber'] = self['thenumber'].to_s.gsub(',','') 
end 

没有worky。

回答

1

用做它的方式是一会儿,非标准化的东西会在对象存在的问题;如果你的代码在属性被标准化之前在属性上工作,那么这将是一个问题。

你可以定义setter:

def thenumber=(value) 
    # normalise stuff here, call write_attribute 
end 

不幸的是我想了很多轨道的形成东西直接写入的属性,这是我不倾向于使用它的原因之一。

或者你可以在控制器中传递参数之前对参数进行标准化。

+0

是的,我已经辞去了自己在控制器中正常化参数,然后他们完全进入AR ... – Bill 2009-05-19 18:40:58

0

红宝石是否让你在一个之间进行交换。和['']? 我不知道,我会稍后再试,但我认为你应该使用。

self.thenumber = self.thenumber.to_s.gsub(',','') 
+0

Nope-尝试这种方式的第一次。 – Bill 2009-05-19 17:10:55

4

我认为你做得对。此测试通过:

test "should remove commas from thenumber" do 
    f = Foo.new(:thenumber => "10,000") 
    f.save 
    f = Foo.find(f.id) 
    assert f.thenumber == "10000"  
end 

我用你的代码。现在

class Foo < ActiveRecord::Base 
    before_validation :normalize 

    def normalize 
    self['thenumber'] = self['thenumber'].to_s.gsub(',','') 
    end 

end 

,我的架构设立数量写是一个字符串,虽然,不是一个整数。

Started 
. 
Finished in 0.049666 seconds. 

1 tests, 1 assertions, 0 failures, 0 errors 

如果你想这些信息存储在数据库作为一个整数,那么你一定需要重写二传手:

def thenumber=(value) 
    self['thenumber'] = value.to_s.gsub(',','').to_i 
end 

如果你做你的方式,用一个整数列,它会通过AR截断....

>> f.thenumber = "10,000" 
=> "10,000" 
>> f.thenumber 
=> 10 

这是一个鲜为人知的事情用Ruby和整数...它自动铸件通过截取任何不再是一个整数。

irb(main):004:0> i = "155-brian-hogan".to_i 
=> 155 

可以是很酷的东西像

/users/155-brian-hogan 

@user = User.find_by_id(params[:id]) 

但不是很爽为你在做什么。

山坳所以要么改变为字符串,并使用过滤器,或改变二传手:)

祝你好运!

+0

感谢您的详细回复! – Bill 2009-05-25 04:16:04

0

您应该从before_validation方法返回true,否则如果表达式被分配到自[“数量写”]最终被零或假的,数据不会被保存,每Rails的机制的文档:

如果before_ *回调返回false,则 所有后续回调和 相关操作都将被取消。

表面上,你试图在这里进行规范化,然后用你的Rails验证检查规范化的结果,这将决定nil/false/blank是否可以。

before_validation :normalize 

def normalize 
    self['thenumber'] = self['thenumber'].to_s.gsub(',','') 
    return true 
end 
+1

只是添加了我希望我在这里看到的注释... before_validation发生在类型转换后,所以如果thenumber是一个数字类型,并且你正在做剥离$和符号,你需要自我['then]'= thenumber_before_type_cast .to_s.gsub(...)before_type_cast版本是自动生成的,如果它已经是一个数字,则需要to_s。 – elc 2013-01-10 19:10:20

7

http://github.com/mdeering/attribute_normalizer看起来像一个有前途的解决这个普遍存在的问题。下面是从主页上的几个例子:

# By default it will strip leading and trailing whitespace 
    # and set to nil if blank. 
    normalize_attributes :author, :publisher 

    # Using one of our predefined normalizers. 
    normalize_attribute :price, :with => :currency 

    # You can also define your normalization block inline. 
    normalize_attribute :title do |value| 
    value.is_a?(String) ? value.titleize.strip : value 
    end 

所以你的情况,你可能会做这样的事情:

normalize_attribute :title do |value| 
    value.to_s.gsub(',', '') 
    end