has_and_belongs_to_many关联表名称

时间:2014-08-29 01:54:10

标签: ruby-on-rails

我试图弄清楚rails如何命名表。我不得不做出反复试验来解决这个问题。

该表最终被命名为menu_categories_items。我想知道它是如何做到的。

模型

# == Schema Information
#
# Table name: menu_categories
#
#  id                 :integer          not null, primary key
#  name               :string(255)
#  order              :integer
#  image_url          :string(255)
#  parent_category_id :integer
#  created_at         :datetime
#  updated_at         :datetime
#

class MenuCategory < ActiveRecord::Base
  belongs_to :parent_category, class_name: "MenuCategory"
  has_and_belongs_to_many :menu_items
end

# == Schema Information
#
# Table name: menu_items
#
#  id          :integer          not null, primary key
#  name        :string(255)
#  description :text
#  price       :decimal(, )
#  order       :integer
#  created_at  :datetime
#  updated_at  :datetime
#

class MenuItem < ActiveRecord::Base
  has_and_belongs_to_many :menu_categories
end

移植

class CreateMenuCategoriesAndMenuItems < ActiveRecord::Migration
  def change
    create_table :menu_categories do |t|
      t.string :name
      t.integer :order
      t.string :image_url
      t.references :parent_category, index: true

      t.timestamps
    end

    create_table :menu_items do |t|
      t.string :name
      t.text :description
      t.decimal :price
      t.integer :order

      t.timestamps
    end

    create_table :menu_categories_items, id: false do |t|
      t.belongs_to :menu_category
      t.belongs_to :menu_item
    end
  end
end

4 个答案:

答案 0 :(得分:3)

来自 API

  

如果您的表共享一个公共前缀,它只会出现一次   开始。例如,表“catalog_categories”和   “catalog_products”生成连接表名称   “catalog_categories_products”

因此,在您的情况下,表格 menu_categories menu_items 具有相同的前缀,名为 menu 。因此,联接表名称将为 menu_categories_items

答案 1 :(得分:3)

<强> HABTM

has_and_belongs_to_many个关联表通常具有[plural_first_alphabetical_model]_[plural_second_alphabetical_model]的命名约定,其前面有任何共享命名

虽然这是Rails标准,但可以使用join_table参数将名称更改为您自己的名称:

#app/models/item.rb
class Item < ActiveRecord::Base
   has_and_belongs_to_many :categories, join_table: "test"
end

#app/models/category.rb
class Category < ActiveRecord::Base
   has_and_belongs_to_many :items, join_table: "test"
end

你可以see how this works here

  

如果您创建了has_and_belongs_to_many关联,则需要   显式创建连接表。除非连接表的名称   使用:join_table选项Active Record明确指定   使用类名的词法顺序创建名称。那么一个   客户和订单模型之间的连接将提供默认连接   表名为“customers_orders”,因为“c”在词汇中超出“o”   排序

-

has_many:通过

has_many :through表通常称为[alphabetical_model_name_singular]_[alphabetical_model_name_plural]

has_many :through的区别在于,由于此关联背后有model,因此您需要了解您的表格将与model本身绑定;这意味着你可以实际调用任何你想要/需要的连接表


<强>建议

我实际上建议您从模型中删除“菜单”,当然,除非它们是更广泛的数据范围的一部分。

您遇到的问题是,每次您希望呼叫关联或数据时,您都必须致电menu_

@item = MenuItem.find 1
@item.menu_categories

这太冗长了。您可以更好地保持代码干燥,允许您通过“自然”名称调用特定对象:

#app/models/item.rb
Class Item < ActiveRecord::Base
   has_and_belongs_to_many :categories
end

#app/models/category.rb
Class Category < ActiveRecord::Base
   has_and_belongs_to_many :items
end

默认情况下,您的HABTM表格为categories_items,您可以拨打以下电话:

@item = Item.find 1
@item.categories

-

<强> OOP

你必须记住Ruby / Rails是object orientated,这意味着每次在应用程序中创建任何功能时,你基本上都必须在中创建应用程序中的对象< / p>

在这里没有详细说明,让我解释一下,您遇到的主要问题之一就是通过调用对象menu_xmenu_y来推卸面向对象的过程。您需要通过“普通”名称来调用对象 - 一个描述它们的简单名称,如果需要将它们与另一个模块相关联。

面向对象开发的目标是执行以下操作:

@item = Item.find 1
@item.switch_menus 2
@item.reload!

看看这是多么“人性化”? OOP开发需要在对象周围创造经验 - 允许您操纵&amp;根据需要更改对象

答案 2 :(得分:1)

Rails命名约定:

数据库表

表名在单词之间具有全部小写字母和下划线,所有表名都需要是复数,例如invoice_items,订单

模型

模型使用不间断的MixedCase的类命名约定命名,并且始终是表名的单数,例如表名可能是订单,型号名称为Order。然后,Rails将在/ app / models目录中的一个名为order.rb的文件中查找类定义。如果模型类名称具有多个大写单词,则假定表名在这些单词之间具有下划线。

控制器

控制器类名称是复数形式的,因此OrdersController将是orders表的控制器类。然后,Rails将在/ app / controllers目录中的一个名为orders_controller.rb的文件中查找类定义。

文件,目录和其他复数

文件使用小写和下划线命名。假设我们有一个Orders控制器,那么将适用以下其他约定:

在app / helpers目录中的orders_helper.rb中有一个名为OrdersHelper的辅助模块 Rails将在app / views / orders目录中查找控制器的视图模板文件 然后,此视图的输出将用于app / views / layouts目录中orders.html.erb中定义的布局 包含order_test.rb的测试文件将在/ test / unit目录中创建,将在/ test / fixtures目录中创建一个名为orders.yml的文件,最后将在/ test / functional中创建一个名为orders_controller_test.rb的文件。目录 首要的关键 假定表的主键名为id。

外键

外键以目标表名的单数形式命名,并附加了_id,例如:物品表中的order_id,其中我们有物品链接到订单表。

多对多链接表

用于连接多对多关系中的两个表的表使用它们链接的表名命名,表名按字母顺序排列,例如items_orders。

自动记录时间戳

您可以让ActiveRecord自动更新数据库表中记录的创建和更新时间。为此,在表中创建两个特别命名的列created_at和updated_at,即t.datetime:created_at和t.datetime:updated_at。如果您只想存储日期而不是日期和时间,请使用:created_on和:updated_on。

答案 3 :(得分:0)

您在迁移中明确创建了表名:create_table :menu_categories_itemscreate_table的第一个参数变为该表名。

如果您使用create_join_table,那么Rails将生成表名 ,并且生成的表名将按联接表的字母顺序排列。

HABTM和create_join_table在生成连接表时都会删除公共前缀,这就是您在表名中只看到“menu_”一次的原因。请参阅derive_join_table_name的定义,了解其执行方式。

您可以通过向table_name提供自己的create_join_table选项来覆盖默认表名。