【问题标题】:Rails 3 joins table and model naming conventionsRails 3 连接表和模型命名约定
【发布时间】:2016-07-16 00:16:05
【问题描述】:

我正在运行 Ruby 2.1.9 和 Rails 3.2.17。

首先,在 Rails 中,我总是假设模型应该几乎总是单数。我见过像 product_categories_product 这样的型号名称。这很好,并且在您希望模型与我看到的关系工作的情况下 instructions_products。在 Rails 中这可能是有道理的,但我宁愿将模型命名为指令产品。这与名为 instructions_products 的连接表相关联。

事实上,我非常沮丧,我开始研究 rails 是如何命名事物的,这会发生吗?很明显,它是模型的一个不错的名称,并且对应于正确的表名。但是什么更合适呢?

ActiveModel::Naming.singular(InstructionsProducts)

返回instructions_products

已编辑:问题的核心是为什么 InstructionsProducts 是 rails 中的有效型号名称以及为什么我上面的示例解析为单数“instructions_products”。考虑到 Rails 约定是保持模型名称单一,这似乎很奇怪。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3


    【解决方案1】:

    你的问题对我来说并不完全清楚。

    根据 Rails 约定,模型名称是单数的,并以驼峰形式书写,例如 InstructionProduct。每个模型都匹配数据库中的一个表,该表具有相同的单词、小写、由“_”分隔且为复数形式。 instruction_products 提供的示例。

    看看下面使用has_many的例子:

    class User < ActiveRecord::Base
      has_many :contacts
    end
    
    class Contact < ActiveRecord::Base
      belong_to :name
    end
    
    user = User.find(1)
    user.contacts # returns an array of all the associated objects
    

    在做user.contacts时,contacts不是表名。它是集合方法,是在 has_many 方法中传递的符号的占位符(请点击 has_many 链接并阅读有关 has_many 的文档说明)。不过也可以使用其他名称:

    class User < ActiveRecord::Base
      has_many :personal_contacts, class_name: 'Contact' #, foreign_key: :contact_id
    end
    
    user = User.find(1)
    user.personal_contacts
    

    class_name 和 foreign_key 是必需的,因为没有遵循 rails 约定。使用has_many :personal_contacts 时,rails 预计personal_contacts 将返回PersonalContact 的数组。

    在 Ruby 中,类名必须以大写字母开头,因此无法创建名为 instruction_product 的类。如果你想提供一个不遵循 Rails 约定的名称,我不建议这样做,你需要通知 rails 新的表名:

    Class AdminUser
      self.table_name = "users"
    end
    

    更新 1:

    如您所知,约定规定模型应声明为单数(class InstructionProduct 而不是class InstructionsProducts。但这只是约定。当类继承自 ActiveRecord::Base 时,会生成 sql 查询, ActiveRecord 将类名小写,单词用_分隔,转换为复数名称作为表名(主要是rails使用InstructionsProducts.model_name.plural,返回instructions_products)。

    您假设单数实际上将名称翻译为单数,即使它是以复数形式编写的,但事实并非如此。它假定您使用的是约定,主要返回带下划线的类名。

    查看rails源码(ActiveModel::Name),好像使用了ActiveSupport::Inflector.underscore(我只是做了很肤浅的调查,不得不承认)。您可以在文档中查看 underscore 的工作原理。

    【讨论】:

    • 我了解类名必须大写,并且 Instruction_product 不是有效的类名。为什么 InstructionsProducts 是 rails 中的有效型号名称?
    • @AndrewStuntz 我提供了更多说明,请告诉我。
    • 我对这个答案不是 100% 满意,但它仍然是一个答案。谢谢你。我自己会做更多的研究。我认为我的主要问题是我正在查看有关 rails 如何处理表名的错误方法。如果我发现任何更有趣的东西,我会更新。
    • @AndrewStuntz 告诉我进展如何。我认为最好的方法是查看 rails 源代码。您可以使用 RubyMine 进行代码钻取。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多