我有三个使用继承的模型,以及一个名为'telecom_circuits'的表。
class Telecom::Circuits::BaseCircuit < ActiveRecord::Base
end
class Telecom::Circuit < ::Telecom::Circuits::BaseCircuit
...
end
class Telecom::Circuits::AttVoiceCircuit < ::Telecom::Circuit
self.table_name = 'telecom_circuits'
end
当我对继承的类进行创建时,它找不到表。
[1] pry(main)> Telecom::Circuits::AttVoiceCircuit
=> Telecom::Circuits::AttVoiceCircuit(id: integer, user_id: integer, division_id: integer, raw_site_id: integer, install_date: date, saville_account_number: string, account_number: string, meg8_account_number: string, main_circuit_id: string, d_channel: string, d_channel_type: string, ds3_access_circuit_id: string, lec_circuit_id: string, cli: string, lso: string, apn_ct1: string, dchan_cost: decimal, monthly_recurring_cost: decimal, created_at: datetime, updated_at: datetime, circuit_provision_type: string, trunk_group: string, apn_ct2: string, slot: string, disconnect_date: datetime, disconnect_requester_id: integer, disconnect_processor_id: integer, telecom_site_id: integer)
[2] pry(main)> Telecom::Circuits::AttVoiceCircuit.create
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'itrc_dev.telecom_base_circuits' doesn't exist: SHOW FULL FIELDS FROM `telecom_base_circuits`
from /Users/mpierc200/.rvm/gems/ruby-1.9.3-p327@itrc/gems/activerecord-3.2.14/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `query'
[3] pry(main)> Telecom::Circuits::AttVoiceCircuit.table_name
=> "telecom_circuits"
如何让继承的类找到该表?请记住,我将需要具有不同表的其他继承类。
答案 0 :(得分:4)
这看起来像Rails 3.2中的一个错误是fixed in Rails 4.0.0。
ETA:实际上,你可能需要add abstract class来解决你的问题然后点击这个bug;)
另请参阅此相关Documentation commit。
再次发出ETA:A closed rails issue听起来也很相关;具有非抽象类和每类表继承看起来不受支持。
答案 1 :(得分:0)
你不应该使用rails继承超过1级,它变得复杂并且不能很好地工作。我有一个类似的结构,只回到了一个继承。
我不确定这是否有效,但您是否也尝试过:
class BaseCircuit < ActiveRecord::Base
end
class Circuit < BaseCircuit
...
end
class AttVoiceCircuit < Circuit
...
end
所以没有命名空间?表名应为“base_circuits”
编辑: 在答案中有人建议问题是有多个级别的继承或命名空间。我尝试了以下方法:
class BaseSo < ActiveRecord::Base
end
class AttVoice < BaseSo
self.table_name = 'telecom_circuits'
end
class ComcastVoice < BaseSo
self.table_name = 'telecom_pri_circuits'
end
这些结果:
[1]pry(main)> AttVoice
=> AttVoice(id: integer, user_id: integer, division_id: integer, raw_site_id: integer, install_date: date, saville_account_number: string, account_number: string, meg8_account_number: string, main_circuit_id: string, d_channel: string, d_channel_type: string, ds3_access_circuit_id: string, lec_circuit_id: string, cli: string, lso: string, apn_ct1: string, dchan_cost: decimal, monthly_recurring_cost: decimal, created_at: datetime, updated_at: datetime, circuit_provision_type: string, trunk_group: string, apn_ct2: string, slot: string, disconnect_date: datetime, disconnect_requester_id: integer, disconnect_processor_id: integer, telecom_site_id: integer)
[2] pry(main)> AttVoice.table_name
=> "telecom_circuits"
[3] pry(main)> ComcastVoice
=> ComcastVoice(id: integer, created_at: datetime, updated_at: datetime, order_submitter: string, division_id: integer, lead_id: integer, pin: integer, raw_site_id: integer, site_poc: string, install_date: date, csg_billing_number: string, gl_code: string, pri_count: integer, pri_type: string, port_native: boolean, did_range: string, did_count: integer, comments: string, telecom_site_id: integer)
[4] pry(main)> ComcastVoice.table_name
=> "telecom_pri_circuits"
[5] pry(main)> AttVoice.count
(41.8ms) SELECT COUNT(*) FROM `telecom_circuits`
=> 2247
[6] pry(main)> AttVoice.create
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'itrc_dev.base_sos' doesn't exist: SHOW FULL FIELDS FROM `base_sos`
from /Users/mpierc200/.rvm/gems/ruby-1.9.3-p327@itrc/gems/activerecord-3.2.14/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `query'
[7] pry(main)> ComcastVoice.count
(0.4ms) SELECT COUNT(*) FROM `telecom_pri_circuits`
=> 155
[8] pry(main)> ComcastVoice.create
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'itrc_dev.base_sos' doesn't exist: SHOW FULL FIELDS FROM `base_sos`
from /Users/mpierc200/.rvm/gems/ruby-1.9.3-p327@itrc/gems/activerecord-3.2.14/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `query'
答案 2 :(得分:0)
你在这里有很多概念。 Ruby继承,Rails STI和命名空间。
首先,您似乎将Ruby的面向对象继承与Rails单表继承(STI)混淆,因为它们都混淆地使用了继承。然而,对于STI而言,关键点是单表。 Rails STI假设所有对象都将保存到一个表中,并且模型会将其类名添加到名为 type 的额外db列中。 STI需要存在此列才能工作。它还允许您通过 class_name
获取它们Telecom::Circuits::Base.all
或
Telecom::Circuits::AttVoice.all
我理解的代码应该是
# in app/telecom/circuit.rb
class Telecom::Circuit < ActiveRecord::Base
...
end
# in app/telecom/circuits/base.rb
class Telecom::Circuits::Base < Telecom::Circuit
...
end
# in app/telecom/circuits/att_voice.rb
class Telecom::Circuits::AttVoice < Telecom::Circuit
...
end
我冒昧地将base和att_voice作为电路的子类,因为我认为它们都是独立的电路类型。如果base具有其他子类共享和添加的功能,那么这个类是多余的,代码将进入Telecom :: Circuit类。
如果这不是您想要的,那么您就不在Rails中使用的ActiveRecord模型中。您可能需要为每个人提供完全成熟的表格。或者,您可以利用DataMapper或新ROM来实现自己的能力。
希望这有帮助!
答案 3 :(得分:0)
模块和mixins会为你处理这个吗?
请参阅here。