Active Record 4.x和MySQL表列类型,不使用迁移

时间:2014-02-06 17:27:24

标签: mysql ruby activerecord sinatra decimal

我正在使用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对象属性方法类型转换?

谢谢, 卢卡

2 个答案:

答案 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