#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