Rails 3 – 轻松使用Pascal Case列名

我们正在开始使用Java / SQL Server数据层编写的新开发的应用程序的Rails 3前端。

由于团队以前的经验,所有列名都是Pascal Case(Id,Name,MyTableId),表名是单数forms(不是复数)。 有没有办法轻松全局覆盖默认的rails约定以使用此数据模型?

我意识到这可以通过使用set_table_name和列别名来完成,但是这种方法违背了使用Rails快速开发应用程序的目的,因为我们必须复制现有的域层代码库。

我发现下面的代码片段有点满足我的需求,这是最好的方式/这仍然有效吗?

http://snippets.dzone.com/posts/show/2034

您的问题的一部分是通过ActiveRecord :: Base上的选项解决的。 在您的environment.rb中,放入

ActiveRecord::Base.pluralize_table_names = false 

据我所知,您的其他问题必须通过深入了解模型生成器代码并找到将属性按到其列名中的位置来解决。 一旦数据库及其模式遵循您的约定,ActiveRecord应该(根据我的理解)使用该约定自动生成其属性。 测试它的简单方法是使用您的约定创建快速记录,在该记录上创建模型,然后使用rails / console在该模型的实例上打印column_names的结果。

编辑:从上面的编辑,我可以看到ActiveRecord的method_missing可能强制执行。 但是,使用该链接可以解决该问题。

当然,要注意使用Pascal案例可能会引起一些令人头疼的问题,因为没有范围解析运算符的大写项目被认为是常量,而不是对象。 例如:

 class Foo attr_reader :low,:Cap def initialize @low = "lowtest" @Cap = "Captest" end def bar self.low #<==works self.Cap #<==works end def baz low #<==works Cap #<==raises NameError end end 

这只意味着您的模型代码需要正确使用self ,无论如何您都应该这样做。

我在这里是我从wilsona那里得到的帮助。 每个答案,补充说

 ActiveRecord::Base.pluralize_table_names = false 

到environment.rb。

我在我的模型目录中添加了这个类,并让我的所有模型inheritance它。

 class PascalCaseActiveRecord < ActiveRecord::Base self.abstract_class = true # all columns are uppercase set_primary_key 'Id' def self.reloadable? false end # convert to camel case attribute if in existence # record.name => record.Name # record.id => record.Id def method_missing(method_id, *args, &block) method_id = method_id.to_s.camelize if @attributes.include? method_id.to_s.camelize.gsub(/=/, '') super(method_id, *args, &block) end # def self.method_missing(method_id, *args) # # if its a finder method # if method_id.to_s.match(/^find_by_/) # puts "Before camelize #{method_id}" # s2 = method_id.to_s.sub("find_by_","").split('_and_') # s2.collect! {|s| s.camelize} # method_id = "find_by_" + s2.join("_and_") # puts "After camelize #{method_id}" # end # # super(method_id, *args) # end # # strip leading and trailing spaces from attribute string values def read_attribute(attr_name) value = super(attr_name) value.is_a?(String) ? value.strip : value end class << self # Class methods private # allow for find_by and such to work with uppercase attributes # find_by_name => find_by_Name # find_by_dob_and_height => find_by_Dob_and_Height def extract_attribute_names_from_match(match) match.captures.last.split('_and_').map { |name| name.camelize } end end end