【问题标题】:Rails: What do I need to do to create a many-to-many relationship between two models within a namespace?Rails:我需要做什么才能在命名空间中的两个模型之间创建多对多关系?
【发布时间】:2015-11-15 23:17:08
【问题描述】:

一个命名空间中有两个模型,它们需要与 has_and_belongs_to_many 以多对多的关系关联。它们是这样创建的:

$ rails generate model namespace/model_a name:string

# app/models/namespace/model_a.rb
class Namespace::ModelA < ActiveRecord::Base
end

$ rails generate model namespace/model_b name:string

# app/models/namespace/model_b.rb
class Namespace::ModelB < ActiveRecord::Base
end

我需要做什么才能成功建立多对多关系?

【问题讨论】:

    标签: ruby-on-rails-4 activerecord namespaces many-to-many has-and-belongs-to-many


    【解决方案1】:

    我在让它工作时遇到了很多问题,但是通过大量解析 Rails 服务器错误消息和数据库客户端,我能够将它按摩到工作中。这是我所做的:

    使用 Rails 4,可以在模型中使用 has_and_belongs_to_many 关系创建关联,并在单独的迁移中使用 create_join_table 创建关联。当然,使用 rails 生成器达不到我们的目标。另请注意,create_join_table 的工作方式不同,甚至可能在以前的 Rails 版本中不可用。

    第 1 步。为连接表生成迁移 命名空间。我们稍后会调整它。

    $ rails g migration CreateModelAModelBJoinTable model_a model_b
    
    # db/migrate/<somenumbers>_create_model_a_model_b_join_table.rb
    class CreateModelAModelBJoinTable < ActiveRecord::Migration
      def change
        create_join_table :model_as, :model_bs do |t|
          # t.index [:model_a_id, :model_b_id]
          # t.index [:model_b_id, :model_a_id]
        end
      end
    end
    

    迁移需要一些按摩。我们需要:

    1. 覆盖表名以考虑命名空间
    2. (可选)选择一个索引。 提示:如果您的命名空间和模型名称很长,如果索引名称超过了数据库规定的字符限制,您可能必须覆盖索引名称。

    这是最终的连接表迁移,注意表名中包含命名空间,但不包括索引中的命名空间。简单地说,这将按照 rails has_and_belongs_to_many 所期望的方式命名表及其索引。

    # db/migrate/<somenumbers>_create_model_a_model_b_join_table.rb
    class CreateModelAModelBJoinTable < ActiveRecord::Migration
      def change
        create_join_table :model_as, :model_bs, table_name: :namespace_model_as_namespace_model_bs do |t|
          t.index [:model_a_id, :model_b_id], name: :index_namespace_model_ab # or whatever, according to your database naming scheme
          # t.index [:model_b_id, :model_a_id]
        end
      end
    end
    

    第 2 步。使用 has_and_belongs_to_many 关联设置我们的模型。

    除了关联,我们还需要覆盖类名和连接表名。

    # app/models/namespace/model_a.rb
    class Namespace::ModelA < ActiveRecord::Base
      has_and_belongs_to_many :namespace_model_b, class_name: "Namespace:ModelB", join_table: "namespace_model_as_namespace_model_bs"
    end
    

    第 3 步。运行数据库迁移

    rake db:migrate
    

    遇到问题的最后提示:

    您可以随时back out a migration,将其删除,然后重新开始:

    $ rake db:rollback STEP=1
    $ rails d migration CreateModelAModelBJoinTable
    

    希望这会有所帮助!

    【讨论】:

    • 在第 1 步的代码中,您忘记在表名前添加冒号 (:)。它应该是 table_name: :namespace_model_as_namespace_model_bs。不管怎样,你的回答对我有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 2021-09-28
    相关资源
    最近更新 更多