Может ли модель A иметь_ одну модель B, которая имеет_and_belongs_to_many модель A? - PullRequest
0 голосов
/ 09 сентября 2018

Вот пример того, что у меня сейчас есть:

#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 :: Ошибка: неизвестный столбец 'platform.company_id' в 'предложении where': SELECT platforms. * FROM platforms ГДЕ platforms. company_id = 1 ПРЕДЕЛ 1):

Есть ли проблема с моей таблицей соединений или я не могу построить свои модели таким образом?

Если я изменю свой has_one :platform на has_and_belongs_to_many :platforms, тогда он отлично работает, поэтому я должен что-то упустить, или это может быть не лучшим способом сделать это.

Моя причина использования has_one состояла в том, что каждый раз, когда я звонил company, я не хотел указывать company.platforms.first.name, а просто набрал бы company.platform.name, так как в любом случае он должен быть только один.

Ответы [ 2 ]

0 голосов
/ 09 сентября 2018

Попробуйте:

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
0 голосов
/ 09 сентября 2018

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, указанный в сообщении об ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...