如何通过关联在has_many上指定连接表?

时间:2015-08-04 17:50:51

标签: ruby-on-rails activerecord active-record-query

以下是我的表格的架构信息:

  • table_name: admin_users ,primary_key:id
  • table_name: UserCompanies ,primary_key:UserCompanyId,foreign_keys:[CompanyId,UserId]
  • table_name:公司,primary_key:CompanyId'

我想做以下事情:

AdminUser.first.companies

但是,到目前为止我的尝试都没有用,我假设是因为我需要指定表名,模型名称或键名,但我不知道如何使用has_many关系。到目前为止,这是我最好的定义:

class AdminUser < ActiveRecord::Base
    has_many :user_companies, class_name:"TableModule::UserCompany", foreign_key:"UserId"
    has_many :companies, through: :user_companies, class_name: "TableModule::Company"
end

# this code is from a rails engine separate from the app where AdminUser is defined
# the purpose of the engine is to provide access to this particular database 
# the CustomDBConventions class adapts the models for this database to work with ActiveRecord so we can use snake case attributes, reference the primary key as 'id', and it specifies the correct tables names.
module TableModule
    class UserCompany < CustomDBConventions
        belongs_to :admin_user
        belongs_to :company
    end

    class Company < CustomDBConventions
        has_many :admin_users, through: :user_companies
    end

    class CustomDBConventions < ActiveRecord::Base
        self.abstract_class = true
        def self.inherited(subclass)
            super
            subclass.establish_connection "table_module_#{Rails.env}".to_sym
            tb_name = subclass.table_name.to_s.gsub(/^table_module_/,"").classify.pluralize
            subclass.table_name = tb_name
            subclass.primary_key = tb_name.singularize + "Id"
            subclass.alias_attribute :id, subclass.primary_key.to_sym
            subclass.column_names.each do |pascal_name|
                subclass.alias_attribute pascal_name.underscore.to_sym, pascal_name.to_sym
                subclass.alias_attribute "#{pascal_name.underscore}=".to_sym, "#{pascal_name}=".to_sym
            end
        end
    end
end

编辑:所以这个设置非常接近,我只缺少1个外键规范。当我运行AdminUser.first.companies时,我收到一个SQL错误:

TinyTds ::错误:列名无效&#39; company_id&#39 ;.:EXEC sp_executesql N&#39; SELECT [Companies]。* FROM [Companies] INNER JOIN [UserCompanies] ON [Companies]。[CompanyId] = [UserCompanies]。[company_id] WHERE [UserCompanies]。[UserId] = @ 0&#39;,N&#39; @ 0 int&#39;,@ 0 = 1

所以我只需要指定在此连接上使用UserCompanies.CompanyId。如何正确指定此外键?

2 个答案:

答案 0 :(得分:2)

假设TableModule :: UserCompany模型具有这些关联......

class TableModule::UserCompany < ActiveRecord::Base
  belongs_to :admin_user
  belongs_to :company
end

...然后我认为这就是你所追求的目标:

class AdminUser < ActiveRecord::Base
  has_many :companies, through: :user_company, class_name: "TableModule::UserCompany"
end

答案 1 :(得分:1)

我不确定您使用TableModule前缀做了什么,但以下情况应该有效:

class AdminUser < ActiveRecord::Base
  has_many :user_companies
  has_many :companies, through: :user_companies
end

class Company < ActiveRecord::Base
  has_many :user_companies
  has_many :admin_users, through: :user_companies
end

class UserCompany < ActiveRecord::Base
  belongs_to :admin_user
  belongs_to :comany
end