2015-06-21 96 views
2

我在做db设计时在我的列之间创建主 - >外键关系。我的数据库设计应该是:Rails belongs_to和has_many没有创建主外键关系

用户表:用户ID(主键),名

Shoppinglist表:商品ID(主键),用户ID(外键)

这里是我的移民文件:

class CreateUsers < ActiveRecord::Migration 
    def change 
    create_table :users do |t| 
     t.integer :userid, :primary_key 
     has_many :shoppinglists, dependent: :destroy 

     t.timestamps null: false 
    end 
    end 
end 

class CreateShoppinglists < ActiveRecord::Migration 
    def change 
    create_table :shoppinglists do |t| 
     t.integer :shoppingid, :primary_key 
     t.belongs_to :userid 

     t.timestamps null: false 
    end 
    end 
end 

没有办法在创建表时创建上述内容,而不是创建新的迁移文件?

我使用这个命令来检查我的关系,我没有看到任何关系创建:

User.reflect_on_all_associations 
+0

此行不是't.belongs_to:userid'。它应该是't.belongs_to:user' – Pavan

+0

为什么你需要明确地创建主键?为什么不能自动使用由轨道生成的那些? – Darpa

回答

3

由于您的迁移无法应用您可能得出结论,它包含错误。你似乎不理解迁移的目的以及它们与模型的区别。另外,你违反了很多约定,所以它会做一些你不期望的事情。

  • has_manybelongs_to不是迁移范围。这些方法来自模型,所添加的只是一些查询方法。他们甚至可以在没有迁移机制的情况下在现有数据库上使用,就像可能那样糟糕。
  • Rails已经为每个表添加了一个主键列id,除非在create_table中有一个选项id: false。因此,添加另一个,并违反约定自己的危险。
  • Rails列命名的惯例是方法命名:snake_case,而不是likethis。它使用这个来适当地复数化和单数化给定的术语来通过惯例来推断配置。因此,外键列的格式为<ASSOCIATION>_id,即。即user_id
  • 最近有外键支持,in Rails 4.2 only,并且由于它没有(如指南要求)与sqlite一起使用,所以Rails默认不添加这些。遵循约定时,您只需指定受影响的表格,Rails将推断其余部分。当然,确保在尝试之前运行Rails 4.2(或更新版本)。在此之前,主外键的概念不属于数据库,而是属于通过has_many和公司生成自己的查询的模型。
2

您可以创建一个迁移是这样的:

rails g migration addShoppingListAssociationToUsers 

,并具有类似的东西以下为迁移内容:

class AddShoppingListAssociationToUser < ActiveRecord::Migration 
    def change 
    add_reference :shoppinglists, :user, index: true, foreign_key: true 
    end 
end 
+0

在创建表格而不是创建新的迁移文件时,是否有创建上述方法的方法?由于我得到一个错误,我的表甚至没有创建。 – fscore

+0

您当然可以使您的其他迁移的以上部分。这样你只有一次迁移。我不确定has_may和belongs_to是否是迁移的一部分。我认为他们只是轨道模型关系的一部分。 – user1801879

1

我假设您不需要显式创建主键,并且可以使用Rails自动为每个表生成的主键。

# User.rb 
has_many :shopping_lists 

# ShoppingList.rb 
belongs_to :user 

# Migration Files 
class CreateUsers < ActiveRecord::Migration 
    def change 
    create_table :users do |t| 
     t.string :name 
     t.timestamps null: false 
    end 
    end 
end 

class CreateShoppinglists < ActiveRecord::Migration 
    def change 
    create_table :shoppinglists do |t| 
     t.references :user, index: true 
     t.timestamps null: false 
    end 
    end 
end 
+0

你在“.rb”文件中列出了哪些内容?我如何运行这些? – fscore

+0

我在.rb文件中编写了两种模型之间的关联。 – Darpa

+0

首先,回滚您之前的迁移并删除早期的迁移文件。然后创建一个新的迁移文件并添加上面提到的用于迁移的代码并迁移它。 – Darpa

相关问题