Rails 4 多态 has_many 忽略 table_name
Rails 4 polymorphic has_many ignores table_name
简短版本:我正在构建一个新的 Rails 4 应用程序,它使用(只读)来自遗留 Rails 2 应用程序所使用的数据库中的一些表,该应用程序仍在使用中.然而,旧应用程序 models/tables 的命名非常混乱(尤其是在新应用程序的上下文中),因此我想使用 self.table_name 为 models/tables 使用不同的名称。在我尝试添加多态关系之前,这一切都完美无缺。 Rails 忽略我定义的 table_name 并使用新模型名称查询类型,这当然是不同的,所以它不起作用。有什么办法可以改变吗?
长版:这个等式中有三个模型,这里是:
class Exporter < MysqlBase
has_many :lic_exporter_addresses, :as => :place
self.table_name = 'excons'
self.primary_key = 'id'
end
class LicBusiness < MysqlBase
has_one :physical_address, -> { where(category: 'Physical') }, :class_name => 'LicExporterAddress', :as => :place
has_one :mailing_address, -> { where(category: 'Mailing') }, :class_name => 'LicExporterAddress', :as => :place
has_many :lic_exporter_addresses, :as => :place
self.table_name = 'businesses'
self.primary_key = 'id'
end
class LicExporterAddress < MysqlBase
belongs_to :place, polymorphic: true
self.table_name = 'addresses'
self.primary_key = 'id'
end
我们有很多不同类型的业务,因此业务模型是最有问题的。我真的不想在新应用程序中使用它,因为它会让人非常困惑 "business" 实际上是什么。使用当前代码,如果我进入 rails 控制台并尝试为 LicBusiness 或 Exporter 获取 lic_exporter_addresses,它会:
SELECT `addresses`.* FROM `addresses` WHERE `addresses`.`place_id` = '00044c693f6848f9b0978f873cf9999a' AND `addresses`.`place_type` = 'LicBusiness'
当我需要的是place_type = 'Business'.
有什么方法可以告诉 Rails 要寻找什么 place_type 吗?我确实看到了这个 question 并且第二个答案看起来很有希望,只是我已经在使用物理地址和邮寄地址来做这件事所以我无法弄清楚如何同时使用这两个选项...感谢您提供任何信息或想法。
在 Rails 4.2 中,用于查询的确切字符串似乎定义为 owner.class.base_class.name
,其中 owner
是声明关联的模型。所以我不认为它是直接支持的。但是我可以想出几种方法来解决这个问题。我认为最有前途的可能是 LicBusiness
:
has_many :lic_exporter_addresses, ->{where place_type: "Business"}, foreign_key: "place_id"
即不要将关联定义为多态的,而是自己定义类型作用域。如果您曾经使用 lic_exporter_address.place = some_lic_business_instance
,这将不会在 lic_exporter_addresses
table 中正确定义 place_type
。但是你说这个 table 是只读的,所以这对你来说实际上可能不是问题。如果是,可能有一些方法可以覆盖该行为以获得您需要的内容。
另外两个想法都让我非常紧张,我认为它们可能会产生意想不到的副作用。他们将覆盖 LicBusiness.base_class
(如果您现在不这样做实际上可能没问题,并且永远不会在 LicBusiness
上设置 STI,但我仍然很紧张),或者覆盖 LicBusiness.name
(我很确定这会产生意想不到的副作用)。
简短版本:我正在构建一个新的 Rails 4 应用程序,它使用(只读)来自遗留 Rails 2 应用程序所使用的数据库中的一些表,该应用程序仍在使用中.然而,旧应用程序 models/tables 的命名非常混乱(尤其是在新应用程序的上下文中),因此我想使用 self.table_name 为 models/tables 使用不同的名称。在我尝试添加多态关系之前,这一切都完美无缺。 Rails 忽略我定义的 table_name 并使用新模型名称查询类型,这当然是不同的,所以它不起作用。有什么办法可以改变吗?
长版:这个等式中有三个模型,这里是:
class Exporter < MysqlBase
has_many :lic_exporter_addresses, :as => :place
self.table_name = 'excons'
self.primary_key = 'id'
end
class LicBusiness < MysqlBase
has_one :physical_address, -> { where(category: 'Physical') }, :class_name => 'LicExporterAddress', :as => :place
has_one :mailing_address, -> { where(category: 'Mailing') }, :class_name => 'LicExporterAddress', :as => :place
has_many :lic_exporter_addresses, :as => :place
self.table_name = 'businesses'
self.primary_key = 'id'
end
class LicExporterAddress < MysqlBase
belongs_to :place, polymorphic: true
self.table_name = 'addresses'
self.primary_key = 'id'
end
我们有很多不同类型的业务,因此业务模型是最有问题的。我真的不想在新应用程序中使用它,因为它会让人非常困惑 "business" 实际上是什么。使用当前代码,如果我进入 rails 控制台并尝试为 LicBusiness 或 Exporter 获取 lic_exporter_addresses,它会:
SELECT `addresses`.* FROM `addresses` WHERE `addresses`.`place_id` = '00044c693f6848f9b0978f873cf9999a' AND `addresses`.`place_type` = 'LicBusiness'
当我需要的是place_type = 'Business'.
有什么方法可以告诉 Rails 要寻找什么 place_type 吗?我确实看到了这个 question 并且第二个答案看起来很有希望,只是我已经在使用物理地址和邮寄地址来做这件事所以我无法弄清楚如何同时使用这两个选项...感谢您提供任何信息或想法。
在 Rails 4.2 中,用于查询的确切字符串似乎定义为 owner.class.base_class.name
,其中 owner
是声明关联的模型。所以我不认为它是直接支持的。但是我可以想出几种方法来解决这个问题。我认为最有前途的可能是 LicBusiness
:
has_many :lic_exporter_addresses, ->{where place_type: "Business"}, foreign_key: "place_id"
即不要将关联定义为多态的,而是自己定义类型作用域。如果您曾经使用 lic_exporter_address.place = some_lic_business_instance
,这将不会在 lic_exporter_addresses
table 中正确定义 place_type
。但是你说这个 table 是只读的,所以这对你来说实际上可能不是问题。如果是,可能有一些方法可以覆盖该行为以获得您需要的内容。
另外两个想法都让我非常紧张,我认为它们可能会产生意想不到的副作用。他们将覆盖 LicBusiness.base_class
(如果您现在不这样做实际上可能没问题,并且永远不会在 LicBusiness
上设置 STI,但我仍然很紧张),或者覆盖 LicBusiness.name
(我很确定这会产生意想不到的副作用)。