生成新模型时,如何具体地指定belongs_to和has_many关系

时间:2019-10-15 19:17:04

标签: ruby-on-rails activerecord orm associations

这是我第一次使用Rails,我没有找到确切的方法来生成具有关联的新模型(和迁移)。例如,我有两个实体:

  • 博客
  • 发布

一个博客可以有多个帖子,而一个帖子属于一个博客。我正在使用以下命令:

rails generate model Blog /* properties... */ post:has_many

rails generate model Post /* properties... */ blog:belongs_to

但是它根本不起作用(阅读:迁移和模型文件不是通过关联生成的)。也许我做错了。我应该在创建所有模型之后才创建关联吗?

还需要在两个模型中或仅在其中一个模型中声明关系吗?

谢谢。

2 个答案:

答案 0 :(得分:0)

对于belongs_to关系,您可以使用:

rails generate model Post /* properties... */ blog:references

我认为您与has_many关系没有任何关系,因为在生成模型和表时,不必在其中包含任何特殊内容。关系在“所属”表中。

为此,您只需使用一个简单的

rails generate model Blog /* properties... */

然后在模型中手动添加has_many :posts:)

答案 1 :(得分:0)

当作为生成器参数belongs_to传入时,只是references的别名,它告诉rails创建一个名为blog_id的列,这是一个外键:

# rails generate model Post blog:belongs_to
class CreatePosts < ActiveRecord::Migration[5.0]
  def change
    create_table :posts do |t|
      t.belongs_to :blog, foreign_key: true
      t.timestamps
    end
  end
end

这是定义两个表之间关系的实际数据库列。

它还将关联添加到模型中

class Post < ApplicationRecord
  belongs_to :blog
end

为什么has_many不能正常工作?

模型生成器的参数是模型的属性。 blog_id是由数据库列支持的实际属性。
has_many不是属性。这是一个元编程方法,它向您的Blog实例添加了posts方法。您需要将其手动添加到模型中。

如果您运行rails g model Blog posts:has_many foo:bar,Rails实际上将使用以下属性创建迁移:

class CreateBlogs < ActiveRecord::Migration[5.0]
  def change
    create_table :blogs do |t|
      t.has_many :posts
      t.bar :foo

      t.timestamps
    end
  end
end

Rails不会键入check参数。当然,迁移实际上不会运行:

undefined method `has_many' for #<ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition:0x007fd12d9b8bc8>

如果您已经生成了迁移,只需删除行t.has_many :posts并将has_many :posts添加到app/models/blog.rb