Как получить ассоциации 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
?
Ответы
Ответ 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
В приведенном выше примере удалите все отношения из базы данных.