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


person Matt Briggs    schedule 13.11.2010    source источник


Ответы (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"

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

person mikej    schedule 13.11.2010
comment
К вашему сведению, ребята, отражения просто возвращают хэш, а не HashWithIn DifferentAccess. Таким образом, ключи хеша .reflections будут либо символом, либо строкой, в зависимости от того, что указано в определении модели. Это просто сбило меня с толку, думая, что это будет или или. - person taelor; 02.04.2012
comment
Как сказал MCB в своем ответе, в Rails 4.2 вы говорите Post.reflections["comments"]вместо этого - person Asfand Qazi; 10.04.2015
comment
спасибо @AsfandYarQazi - я обновил ответ, чтобы учесть различия для Rails 4.2+ - person mikej; 12.04.2015
comment
ваш ответ поможет мне улучшить сбор информации о базе данных Rails: gist.github.com/r72cccp/3480f4e13f00d54d4cb87bfd4077c8afd4077c8afd4077c8afd4077c8afd4077c8aa - person Sergio Belevskij; 20.08.2016

Для будущих гуглеров в Rails 4 ответ будет таким:

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

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

РЕДАКТИРОВАТЬ:

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

person MCB    schedule 03.01.2014

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

object._reflections

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

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

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

person Lucivaldo Castro    schedule 09.03.2016
comment
Не рекомендуется использовать подчеркнутые методы в Rails, они могут измениться в любой момент без предупреждения, что вызовет ошибки при обновлении. - person camilo.forero; 18.10.2019