【发布时间】:2011-08-23 22:08:41
【问题描述】:
我的数据库表和字段名称是 CamelCase。是否可以即时将这些名称转换为snake_case?让模型方法看起来漂亮?
该应用是 JRubyOnRails 3.0 / MSSQL DB / ActiveRecord-JDBC-adapter。
【问题讨论】:
标签: ruby-on-rails ruby jruby activerecord-jdbc
我的数据库表和字段名称是 CamelCase。是否可以即时将这些名称转换为snake_case?让模型方法看起来漂亮?
该应用是 JRubyOnRails 3.0 / MSSQL DB / ActiveRecord-JDBC-adapter。
【问题讨论】:
标签: ruby-on-rails ruby jruby activerecord-jdbc
@arkadiy,事实上,就在今天,我正在调查这个问题。
对于表名,我们当然有set_table_name 方法:
class CamelCasedFoo < ActiveRecord::Base
set_table_name :CamelCasedTable
end
对于像主键这样的东西,我们有set_primary_key:
class CamelCasedBar < ActiveRecord::Base
...
set_primary_key "CamelCasedTableID"
end
而且应该可以使用alias_attribute 将时髦的、遗留的列名称别名为更适合rails 的名称:
class CamelCasedBaz < ActiveRecord::Base
...
alias_attribute :preferred_delivery, :DeliveryFrequency
end
要记住的关键一件事是注意任何列名称为 ruby 或 rails keywords 或 magic field names。
Rails 似乎具有元编程的所有优点,可以让您处理遗留的数据库表名和列。您可能希望阅读 Jonathan Hui 在"Ruby on Rails 3 Model Working with Legacy Database" 上的博客文章。你可能想看看safe_attributes gem。
【讨论】:
我也有同样的需要。 @buruzaemon 设置 table_name 和 primary_key 的答案很好,但我有一些建议可以让它变得更好。
我相信 set_* 样式方法已经失宠,现在建议直接设置属性。所以
class Project < ActiveRecord::Base
self.table_name = 'Projects'
self.primary_key = 'ProjectId'
end
此外,使用 alias_attribute 手动为每个属性设置别名似乎很乏味。似乎也很容易忘记一个。尽管@Behrangf 建议不要这样做,但我认为使用一点元编程魔法来自动提供属性的snake_case 版本没有任何问题。 I've created a module 自动执行此操作。它甚至不与 ActiveRecord 绑定,因此您也可以在 API 包装器或其他镜像不遵循 Ruby 约定的系统的东西中使用它。我正在跟踪 Gist 上的模块,但为方便起见,转载如下:
module Snakeable
# Patch in our automatic snake_case methods
def method_missing method, *args
if is_snake_case?(method) &&
respond_to?(camelized = method.to_s.camelize.to_sym)
send camelized, *args
else
super
end
end
# So the object including this module will respond to
# Object#respond_to? correctly
def respond_to? method, *args
super || (
is_snake_case?(method) &&
super(method.to_s.camelize.to_sym, *args)
)
end
private
# Is the given method using the snake_case format
def is_snake_case? method
method.to_s =~ /^[a-z]+(?:_[a-z]+)*[?=!]?$/
end
end
这个模块确实依赖于 ActiveSupport 的camelize 方法。
【讨论】:
呸!你有我的同情。我一直喜欢 old_school.names,即使引擎允许其他恶意软件...
我认为这是一个旧版应用程序?
如何为您的 Rails 应用创建一组视图?
【讨论】:
Ruby on Rails 是 opinionated software。这意味着它的设计者选择了以特定方式做事,并且为了能够成功、愉快、轻松、顺畅地使用 RoR,等等。您必须以特定方式来做。因此,如果您不能或不想遵循 RoR 的表和列命名约定,建议您选择其他框架。
但是,如果您想继续使用 RoR 但又想要 snake_case 方法名称,则可以打开 ActiveRecord::Base 类,拦截对未定义方法的调用,确保它们与 ^[a-z]+(_[a-z]+)*$ 常规异常匹配,如果是这样,将它们转换为大写并调用大写方法。 但我强烈建议你不要那样做!!!* :D
【讨论】:
Foo.find(:all, :include => :bars ) 无法使用 ATM,因为我的 bars 表被命名为 tblBar。在我们的应用程序中没有办法解决这个问题。在非主见的框架中,您甚至可以拥有复合主键,但使用 ActiveRecord,您的 PK 应该是单列的。