2011-06-20 19 views
0

我有以下三種模式的ActiveRecord :: HasManyThroughAssociationNotFoundError問題,與一捻

LegacyRole:

class LegacyRole < LegacyModel 
    has_many :permissions_roles 
    has_many :permissions, :through => :permissions_roles 
end 

LegacyPermissionsRole:

class LegacyPermissionsRole < LegacyModel 
    belongs_to :role 
    belongs_to :permission 
end 

和LegacyPermission:

class LegacyPermission < LegacyModel 
    has_many :permissions_roles 
    has_many :roles, :through => :permissions_roles 
end 

而爲了讓這些所有的工作,並連接遺留數據庫和諸如此類的東西,我有下面的類LegacyModel這可能是想成爲太聰明......

require 'active_record' 

class LegacyModel < ActiveRecord::Base 
    self.abstract_class = true 

    establish_connection "legacy_#{::Rails.env}" 

    def self.inherited(subclass) 
    tabeleized_name = subclass.name.tableize 
    raise "Legacy models must be prefixed with 'Legacy'" unless tabeleized_name.start_with?('legacy_') 

    logger.info "***********LOAD***********" 
    logger.info "Loaded legacy model: #{subclass.name} using table: #{tabeleized_name.gsub('legacy_', '')}" 
    super 
    subclass.set_table_name tabeleized_name.gsub('legacy_','') 
    end 


    # these methods do much the same thing, can probably abstract some of this out 
    def self.belongs_to(association_id, options = {}) 
    new_association = association_id.to_s.insert(0, 'legacy_').to_sym 
    old_association = association_id 


    logger.info "Legacy model has belongs_to association: '#{association_id}'" 
    association_id = association_id.to_s.insert(0, 'legacy_').to_sym 
    logger.info "Converting association to: '#{association_id}'" 

    unless options.has_key?(:foreign_key) 
     # our foreign_key is missing 
     options[:foreign_key] = old_association.to_s.foreign_key 
     logger.info("Foreign_key was missing, is now: #{options[:foreign_key]}") 
    end 

    super 
    alias_method old_association, new_association 
    end 

    def self.has_many(association_id, options = {}) 
    new_association = association_id.to_s.insert(0, 'legacy_').to_sym 
    old_association = association_id 


    logger.info "Legacy model has_many to association: '#{association_id}'" 
    association_id = association_id.to_s.insert(0, 'legacy_').to_sym 
    logger.info "Converting association to: '#{association_id}'" 
    logger.debug("Association options are: #{options.inspect}") 

    if options.has_key?(:through) 
     options[:through] = options[:through].to_s.insert(0, 'legacy_') 
     logger.info("Through mutated, is now: #{options[:through]}") 
    end 

    super 
    alias_method old_association, new_association 
    end 

end 

每當我嘗試訪問權限上LegacyRole的情況下,我得到下面的活動記錄錯誤: 的ActiveRecord :: HasManyThroughAssociationNotFoundError:找不到模型協會「legacy_permissions_roles」 LegacyRole

我經歷這一切踩盡我所能,我真的不能弄清楚爲什麼會發生這種情況,顯然這比LegacyModel類的標準稍微複雜一些,我真的不知道如何診斷這更進一步......我現在正處在我無法看到樹林的地方,並覺得它可能只是一件非常簡單的事情,我錯過了!

編輯:

下面是從模型加載輸出日誌

**************************** 
Loaded legacy model: LegacyPermission using table: permissions 
Legacy model has_many association: 'permissions_roles' 
Converting association to: 'legacy_permissions_roles' 
Association options are: {} 
Legacy model has_many association: 'roles' 
Converting association to: 'legacy_roles' 
Association options are: {:through=>:permissions_roles} 
Changed :through to: 'legacy_permissions_roles' 

**************************** 
Loaded legacy model: LegacyPermissionsRole using table: permissions_roles 
Legacy model has belongs_to association: 'role' 
Converting association to: 'legacy_role' 
Legacy model has belongs_to association: 'permission' 
Converting association to: 'legacy_permission' 
Foreign_key was missing, is now: 'permission_id' 

**************************** 
Loaded legacy model: LegacyRole using table: roles 
Legacy model has_many association: 'permissions_roles' 
Converting association to: 'legacy_permissions_roles' 
Association options are: {} 
Legacy model has_many association: 'permissions' 
Converting association to: 'legacy_permissions' 
Association options are: {:through=>:permissions_roles} 
Changed :through to: 'legacy_permissions_roles' 

回答

0

也許你想

class LegacyRole < LegacyModel 
    has_many :permissions_roles 
    has_many :permissions, :through => :legacy_permissions_roles # note the `legacy` prefix 
end 

或者這是您的文章錯字?

+0

導致...找不到該協會「legacy_legacy_permissions_roles」模型LegacyRole :) 協會名稱在LegacyModel突變爲前綴legacy_讓一切電線正確使用(當然,希望)最小做文章。 我有一個偷偷摸摸的軌道檢查類文件源並發現不一致,由於這...不知道雖然! – Lee

+1

糟糕,我沒有注意到...... Rails不應該檢查類文件。至多,它應該檢查'schema.rb'文件。你可能想嘗試沒有自動加前綴,看看是否有效(你永遠不知道......)。此外,你可能想檢查模型的反射(我在這裏簡單地寫了一下:http://davidsulc.com/blog/2011/06/19/leveraging-active-record-reflections/),看看這種關係是否存在正確註冊。 –

+0

如果我不更改LegacyModel中的選項[:through] * AND *在LegacyRole中包含:through =>:legacy_permissions_roles,則會收到未知列'permissions_roles.legacy_role_id',這實際上使得一點意義(並且應該很容易黑客/修復),但這只是我手動做什麼LegacyModel應該自動做...謝謝雖然,我認爲你的意見可能會讓我在正確的軌道上! – Lee