我正在使用Sinatra v1.4.4和Active Record v4.0.2进行一些测试。我已经创建了一个DBase和一个名为Company with Mysql Workbench的表。在表格公司中有两个字段lat&分别为DECIMAL(10,8)和DECIMAL(11,8)类型。在不使用迁移的情况下,我将公司模型定义如下:
class Company < ActiveRecord::Base
end
除了lat和lng作为字符串而不是float / decimal这一事实外,一切正常。有没有办法在上面的Class Company定义中定义类型。在这里,您可以找到提供JSON响应的Sinatra路线:
get '/companies/:companyId' do |companyId|
begin
gotCompany = Company.find(companyId)
[200, {'Content-Type' => 'application/json'}, [{code:200, company: gotCompany.attributes, message: t.company.found}.to_json]]
rescue
[404, {'Content-Type' => 'application/json'}, [{code:404, message:t.company.not_found}.to_json]]
end
end
Active Record正确识别它们为十进制。例如,执行此代码:
Company.columns.each {|c| puts c.type}
可能是它的Active Record对象属性方法类型转换?
谢谢, 卢卡
答案 0 :(得分:2)
您可以为这些属性包装getter方法并进行转换:
class Company < ActiveRecord::Base
def lat
read_attribute(:lat).to_f
end
def lng
read_attribute(:lng).to_f
end
end
这将把它们转换成浮点数,例如:
"1.61803399".to_f
=> 1.61803399
修改强>
想要更具声明性的方式吗?只需展开ActiveRecord::Base
:
# config/initializers/ar_type_casting.rb
class ActiveRecord::Base
def self.cast_attribute(attribute, type_cast)
define_method attribute do
val = read_attribute(attribute)
val.respond_to?(type_cast) ? val.send(type_cast) : val
end
end
end
然后像这样使用它:
class Company < ActiveRecord::Base
cast_attribute :lat, :to_f
cast_attribute :lng, :to_f
end
现在,当您在实例上调用这些方法时,它们将被类型化to_f
。
答案 1 :(得分:0)
根据diego.greyrobot的回复,我使用其他方法修改了我的公司类。它会覆盖属性方法,然后对所需字段进行类型转换。然而,更具声明性的东西将是可取的。
class Company < ActiveRecord::Base
def attributes
retHash = super
retHash['lat'] = self.lat.to_f
retHash['lng'] = self.lng.to_f
retHash
end
end