【问题标题】:How do I specific belongs_to and has_many relationships when generating new models生成新模型时如何指定belongs_to 和has_many 关系
【发布时间】:2019-10-15 19:17:04
【问题描述】:

这是我第一次使用 Rails,我不知道如何通过关联生成新模型(和迁移)。例如,我有两个实体:

  • 博客
  • 发布

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

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

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

但它根本不起作用(阅读:迁移和模型文件没有与关联一起生成)。也许我做错了什么。是否应仅在创建所有模型后才创建关联?

另外,是否需要在两个模型中声明关系,还是只在其中一个模型中声明?

谢谢。

【问题讨论】:

    标签: ruby-on-rails activerecord orm associations


    【解决方案1】:

    当作为生成器参数传递时,belongs_to in 只是 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 不是属性。这是一种元编程方法,可将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 不对参数进行类型检查。当然迁移实际上不会运行:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-15
        相关资源
        最近更新 更多