模型A的has_one模型B的has_and_belongs_to_many模型A可以吗?

时间:2018-09-09 18:55:03

标签: ruby-on-rails

这是我目前所拥有的示例:

#app/models/company.rb
class Company < ApplicationRecord
    has_one :platform
end

#app.models/platform.rb
class Platform < ApplicationRecord
    has_and_belongs_to_many :companies
end

还有一个迁移,它创建了一个联接表以将平台与多个公司链接

class CreateJoinTableCompanyPlatforms < ActiveRecord::Migration[5.1]
  def change
    create_join_table :companies, :platforms do |t|
      t.index [:company_id, :platform_id]
      t.index [:platform_id, :company_id]
    end
  end
end

但是,当我进入视图并尝试致电Company.first.platform时,出现此错误:

  

ActionView :: Template :: Error(Mysql2 :: Error:未知列   “ where子句”中的“ platforms.company_id”:SELECT platforms。* FROM   platformsplatforms处。company_id = 1 LIMIT 1):

我的联接表是否存在问题,或者我不能像这样构造我的模型吗?

如果我将has_one :platform更改为has_and_belongs_to_many :platforms,那么它可以正常工作,因此我必须丢失某些东西,否则这可能不是最好的方法。

我使用has_one的原因是因为每次我致电company时,我都不想指定company.platforms.first.name,而宁愿只做company.platform.name,因为反正应该只有一个。

2 个答案:

答案 0 :(得分:2)

has_and_belongs_to_many用于对称使用;换句话说,如果平台模型使用它来指向公司,那么公司模型应该使用它来指向平台。尝试将其与另一种类型的关联配对会失败,并且会失败。

如果您希望company.platform.name工作,您是否考虑过has_many关系?像这样:

class Company < ApplicationRecord
  belongs_to :platform
end

class Platform < ApplicationRecord
  has_many :companies
end

这种类型的关系不需要联接表。而是使用错误消息中提到的platform.company_id列。

答案 1 :(得分:1)

尝试一下:

rails g scaffold Platform name
rails g scaffold Company name platform:references

使用inverse_of编辑模型

class Company < ApplicationRecord
  belongs_to :platform, inverse_of: companies
end

class Platform < ApplicationRecord
  has_many :companies, inverse_of: platform
end

创建平台和公司

Platform.create({name: 'pl47'})
Company.create({name: 'My Company', platform: Platform.first })
Company.create({name: 'Your Company', platform: Platform.first })

现在您可以使用:

Company.first.platform
Company.first.platform.name
Platform.find(1).companies
Platform.find(1).companies.each do |company|
  puts company.name
end