Подтвердить что ты не робот

Как получить ассоциации activerecord через отражение

Для обычных столбцов вы можете получить их с помощью метода класса columns. Однако ассоциации могут быть названы совсем другими, если параметр foreign_key задан в методе отношений. Например, данный

class Post
  has_many :comments, :foreign_key => :message_id # this is a contrived example
end

Если бы я сделал Post.column_names, я мог бы получить message_id, но есть ли способ получить comments?

4b9b3361

Ответ 1

Model.reflections дает информацию об ассоциациях моделей. Это имя Hash связано с именем ассоциации. например.

Post.reflections.keys # => ["comments"]

Вот пример некоторой информации, которую он может использовать для доступа:

Post.reflections["comments"].table_name # => "comments"
Post.reflections["comments"].macro # => :has_many
Post.reflections["comments"].foreign_key # => "message_id"

Примечание. Этот ответ был обновлен, чтобы включить Rails 4.2 на основе MCB ответа и комментариев ниже. В ранних версиях Rails обратное отражение foreign_key было доступно с помощью primary_key_name вместо этого, а ключи для отражений могут быть символами вместо строк в зависимости от того, как была определена ассоциация, например. :comments вместо "comments".

Ответ 2

Для будущих Googlers in Rails 4 теперь будет отвечать:

Post.reflections[:comments].foreign_key # => "message_id"

Взято отсюда: fooobar.com/questions/111623/...

EDIT:

reflections, начиная с 4.2, теперь берет строки вместо символов, которые являются забавной ошибкой для отслеживания. Если вы хотите продолжать использовать символы, вы должны переключиться на reflect_on_association(:assoc_name). Также обратите внимание, что reflections на самом деле публичный api, который будет сообщать о таких вещах, как HABTM, даже несмотря на то, что все это проходит через капот. Отражения Rails на самом деле используются в _reflections

Ответ 3

Для объекта ActiveRecord я использую:

object._reflections

Итак, я могу манипулировать возвратом Хэша. Например:

object._reflections.keys.each do |key|
    object.public_send(key).destroy_all
end

В приведенном выше примере удалите все отношения из базы данных.