has_many: с помощью class_name и foreign_key не работает

#ruby-on-rails #ruby #foreign-keys #has-many-through

#ruby-on-rails #ruby #внешние ключи #имеет много сквозных

Вопрос:

мне нужно создать родительское отношение, то есть дочернее и родительское отношение в модели клиента. Для хранения информации о родительском и дочернем элементах я создал таблицу соединений, то есть ParentalRelation. Моя модель клиента:

 class Customer < ApplicationRecord
  has_many :parental_relations
  has_many :children, class_name: 'Customer', foreign_key: 'child_id', through: :parental_relations
  has_one :parent, foreign_key: 'parent_id', class_name: 'Customer', through: :parental_relations, source: :parent
end
  

Моя модель parental_relation:

 class ParentalRelation < ApplicationRecord
  belongs_to :parent, class_name: 'Customer'
  belongs_to :child, class_name: 'Customer'
end
  

Я пытаюсь получить данные с помощью:

 Customer.first.children
  

Но я не получаю данные. получается так, даже когда есть данные:

Клиент::ActiveRecord_Associations_CollectionProxy:0x3fe49a819750

Было бы действительно большой помощью, если бы кто-нибудь мог мне помочь. Заранее благодарю вас

Ответ №1:

если у parent_relation есть столбец, parent_id и child_id я считаю, что это должно быть

 class Customer < ApplicationRecord
  has_many :children_relations, class_name: 'ParentalRelation', foreign_key: 'parent_id'
  has_many :children, class_name: 'Customer', foreign_key: 'parent_id', through: :children_relations, source: :child
  
  has_one :parent_relation, class_name: 'ParentalRelation', foreign_key: 'child_id'
  has_one :parent, foreign_key: 'parent_id', class_name: 'Customer', through: :parent_relation, source: :parent
end
  

в соответствии с вашим отношением, Rails будет вызывать sql SELECT "customers".* FROM "customers" INNER JOIN "parental_relations" ON "customers"."id" = "parental_relations"."child_id" WHERE "parental_relations"."customer_id" = $1 LIMIT $2

Но я не знаю вашу структуру таблицы. Таким образом, вы можете прочитать sql в консоли rails и узнать, как Rails находит записи. Это должно помочь вам решить эту проблему.

Комментарии:

1. родительское отношение определяется: has_one:parent, foreign_key: ‘child_id’, class_name: ‘Customer’, через: :parent_relation, source: :parent

Ответ №2:

Учитывая, что у вас есть customer has_one :parent в вашей модели, похоже, что вы пытаетесь создать отношение «один ко многим». Если это правильно, вам не нужна таблица объединения. Вам нужна таблица объединения только в том случае, если вы создаете отношения «многие ко многим».

Чтобы сделать это как один ко многим, удалите ParentalRelation model и таблицу и обновите свой класс customer примерно так:

 class Customer < ApplicationRecord
  belongs_to parent, class_name: "Customer"
  has_many children, class_name: "Customer", foreign_key: :parent_id
end
  

Ознакомьтесь с приведенными здесь руководствами по созданию таблицы с самосоединением:
https://guides.rubyonrails.org/association_basics.html#self-joins

Как только у вас это будет, вы сможете это сделать:

 Customer.first.children