代码之家  ›  专栏  ›  技术社区  ›  Dimitri Cabete Jorge

在两个不同的数据库中遇到ActiveRecord的关系问题

  •  0
  • Dimitri Cabete Jorge  · 技术社区  · 5 年前

    我正在尝试设置 has_many :through 两个不同数据库之间的关系并遇到问题。

    我的模型如下:

    公司 :

    # this model lives in database main_db
    class Company < ActiveRecord::Base
      has_many :company_custom_plans
      has_many :custom_plans, through: :company_custom_plans
    end
    

    定制计划

    # this model lives in database other_app_db
    class CustomPlan < ActiveRecord::Base
      has_many :company_custom_plans
      has_many :companies, through: :company_custom_plans
    end
    
    

    节理模型 :

    # this model lives in other_app_db
    class CompanyCustomPlan < ActiveRecord::Base
      belongs_to :custom_plan
      belongs_to :company
    end
    
    ### Schema ###
    #  create_table "company_custom_plans", force: :cascade do |t|
    #    t.integer "company_id",     limit: 4, null: false
    #    t.integer "custom_plan_id", limit: 4, null: false
    #  end
    

    因此,它在公司模型上非常有效,但是当尝试在CustomPlan上使用此关系时,我会得到一个错误,因为有许多:通过查找 company_custom_plans 在里面 main_db 而不是 other_app_db

    例子:

    ccp = CompanyCustomPlan.create!(company: company, custom_plan: custom_plan)
    company.company_custom_plans == [ccp] # true
    company.custom_plans == [custom_plan] # true
    custom_plan.company_custom_plans == [ccp] # true
    
    custom_plan.companies # error
    ActiveRecord::StatementInvalid: Mysql2::Error: Table 'main_db.company_custom_plans' doesn't exist: SHOW FULL FIELDS FROM `company_custom_plans`
    

    我试着用不同的方法玩:通过 source: 'company' )但无法弄清楚如何使这项工作发挥作用。

    谢谢,

    2 回复  |  直到 5 年前
        1
  •  3
  •   max    5 年前

    为以下对象命名联接模型时 has_many through: 关联(或具有复合名称的模型)的格式应为 SingularSingular 对于模型和 singular_plural 为了桌子。所以你应该给模型命名 CompanyCustomPlan 桌子 company_custom_plans . 这和 has_and_belongs_to_many .

    例如:

    class User
      has_many :user_courses
      has_many :courses, though: :user_courses
    end
    
    class Course
      has_many :user_courses
      has_many :users, though: :user_courses
    end
    
    class UserCourse
      belongs_to :user
      belongs_to :course
    end
    

    这将正确地将关联映射到用户课程类。如果我们曾经用过 has_many :users_courses 我们会得到 NameError: uninitialized constant Users::Courses 由于ActiveRecord从关联中派生类名的方式,复数单词被解释为模块!

    当然,您可以通过提供 class_name 但是,如果你没有充分的理由不这么做,那么遵循惯例可能是一个更好的主意。

    当然,如果有更好地描述域的东西,您可以对连接模型使用完全不同的名称-例如 Enrollment 而不是 UserCourse .

        2
  •  0
  •   Dimitri Cabete Jorge    5 年前

    我最终发现了如何强制 has_many :through 要使用下面的正确数据库,请执行以下操作 stackoverflow answer .

    class CompanyCustomPlan < ActiveRecord::Base
    
      self.table_name = "#{ActiveRecord::Base.connection.current_database}.company_custom_plans"
    
      belongs_to :custom_plan
      belongs_to :company
    end