Как получить ассоциации 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?

3   51  

3 ответа:

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"

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

для будущих гуглеров в Rails 4 Ответ теперь будет:

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

Взято отсюда:https://stackoverflow.com/a/15364743/2167965

EDIT:

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

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

object._reflections

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

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

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