【问题标题】:CamelCase instead of snake_case in Rails DB在 Rails DB 中用 CamelCase 代替 snake_case
【发布时间】:2011-08-23 22:08:41
【问题描述】:

我的数据库表和字段名称是 CamelCase。是否可以即时将这些名称转换为snake_case?让模型方法看起来漂亮?

该应用是 JRubyOnRails 3.0 / MSSQL DB / ActiveRecord-JDBC-adapter。

【问题讨论】:

    标签: ruby-on-rails ruby jruby activerecord-jdbc


    【解决方案1】:

    @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 keywordsmagic field names

    Rails 似乎具有元编程的所有优点,可以让您处理遗留的数据库表名和列。您可能希望阅读 Jonathan Hui 在"Ruby on Rails 3 Model Working with Legacy Database" 上的博客文章。你可能想看看safe_attributes gem。

    【讨论】:

      【解决方案2】:

      我也有同样的需要。 @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 方法。

      【讨论】:

        【解决方案3】:

        呸!你有我的同情。我一直喜欢 old_school.names,即使引擎允许其他恶意软件...

        我认为这是一个旧版应用程序?

        如何为您的 Rails 应用创建一组视图?

        【讨论】:

          【解决方案4】:

          Ruby on Rails 是 opinionated software。这意味着它的设计者选择了以特定方式做事,并且为了能够成功、愉快、轻松、顺畅地使用 RoR,等等。您必须以特定方式来做。因此,如果您不能或不想遵循 RoR 的表和列命名约定,建议您选择其他框架。

          但是,如果您想继续使用 RoR 但又想要 snake_case 方法名称,则可以打开 ActiveRecord::Base 类,拦截对未定义方法的调用,确保它们与 ^[a-z]+(_[a-z]+)*$ 常规异常匹配,如果是这样,将它们转换为大写并调用大写方法。 但我强烈建议你不要那样做!!!* :D

          【讨论】:

          • Rails 可能是固执己见的软件,但如果您决定从陈旧的小路上远足,它肯定不会阻止您选择从悬崖上走。 :-)
          • “因此,如果您不能或不想遵循 RoR 的表和列命名约定,建议您选择另一个框架”。我不同意那个建议。 “自以为是”并不意味着严格,只要遵循惯例,就会更容易。我曾多次使用不遵循 Rails 约定的遗留模式,并取得了成功。
          • 你说的叫“约定或配置”。 RoR 遵循 CoC,但它是固执己见的软件。它不是为通用框架而设计的。我已经/正在使用自定义模式命名约定的项目中使用 RoR,并且大多数 RoR 的查询功能对我们不起作用,我们必须回退到 SQL 查询。
          • 没关系。我并不是说 RoR 将适用于任何模式,也许它不适用于这里的 @arkadiy。但是您是说除非架构遵循 RoR 约定,否则 RoR 将无法工作,我不同意。
          • 它没有按应有的方式工作。例如,对我来说,Foo.find(:all, :include =&gt; :bars ) 无法使用 ATM,因为我的 bars 表被命名为 tblBar。在我们的应用程序中没有办法解决这个问题。在非主见的框架中,您甚至可以拥有复合主键,但使用 ActiveRecord,您的 PK 应该是单列的。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-25
          • 1970-01-01
          • 2021-11-06
          相关资源
          最近更新 更多