在两个不同的数据库上遇到与 ActiveRecord has_many 的关系问题
Encountering relationship issues with ActiveRecord has_many through on two different databases
我正在尝试在两个不同的数据库上建立 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
custom_plan
# 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
所以它在 Company 模型上工作得很好但是当试图在 CustomPlan 上使用这个关系时我得到一个错误因为 has_many :through 在 [= 中寻找 company_custom_plans
17=] 而不是 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`
我尝试使用 has_many 的不同选项:through(例如设置 source: 'company'
),但不知道如何实现。
谢谢,
在为 has_many through:
关联(或具有复合名称的一般模型)命名连接模型时,您应该遵循模型的 SingularSingular
格式和 table。所以你应该命名模型 CompanyCustomPlan
和 table 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
这会将关联正确映射到 UserCourse class。如果我们使用 has_many :users_courses
我们会得到 NameError: uninitialized constant Users::Courses
由于 ActiveRecord 从关联派生 class 名称的方式 - 复数词被解释为模块!
您当然可以通过提供 class_name
选项来覆盖它,但是首先遵循惯例可能是一个更好的主意,除非您有充分的理由不这样做。
如果有更好地描述域的东西,您当然可以为连接模型使用完全不同的名称 - 例如 Enrollment
而不是 UserCourse
。
我最终弄清楚了如何强制 has_many :through
在 Whosebug answer 之后使用正确的数据库。
class CompanyCustomPlan < ActiveRecord::Base
self.table_name = "#{ActiveRecord::Base.connection.current_database}.company_custom_plans"
belongs_to :custom_plan
belongs_to :company
end
我正在尝试在两个不同的数据库上建立 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
custom_plan
# 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
所以它在 Company 模型上工作得很好但是当试图在 CustomPlan 上使用这个关系时我得到一个错误因为 has_many :through 在 [= 中寻找 company_custom_plans
17=] 而不是 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`
我尝试使用 has_many 的不同选项:through(例如设置 source: 'company'
),但不知道如何实现。
谢谢,
在为 has_many through:
关联(或具有复合名称的一般模型)命名连接模型时,您应该遵循模型的 SingularSingular
格式和 table。所以你应该命名模型 CompanyCustomPlan
和 table 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
这会将关联正确映射到 UserCourse class。如果我们使用 has_many :users_courses
我们会得到 NameError: uninitialized constant Users::Courses
由于 ActiveRecord 从关联派生 class 名称的方式 - 复数词被解释为模块!
您当然可以通过提供 class_name
选项来覆盖它,但是首先遵循惯例可能是一个更好的主意,除非您有充分的理由不这样做。
如果有更好地描述域的东西,您当然可以为连接模型使用完全不同的名称 - 例如 Enrollment
而不是 UserCourse
。
我最终弄清楚了如何强制 has_many :through
在 Whosebug answer 之后使用正确的数据库。
class CompanyCustomPlan < ActiveRecord::Base
self.table_name = "#{ActiveRecord::Base.connection.current_database}.company_custom_plans"
belongs_to :custom_plan
belongs_to :company
end