Як отримати асоціації активних записів за допомогою рефлексії

Для звичайних стовпців ви можете отримати їх за допомогою методу класу 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
До вашої інформації, хлопці, reflections просто повертає хеш, а не HashWithIndifferentAccess. Отже, ключі хешу .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/3480f4e13f00d54d4cb87bfd40 77c8aa - person Sergio Belevskij; 20.08.2016

Для майбутніх співробітників Google у 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