Rails определяет, является ли ассоциация has_one или has_many

Интересно, есть ли простой способ динамически определить, является ли ассоциация модели отношением "has_one" или "has_many" (т.е. является ли это ассоциацией с одним объектом или многими).

Я использую MongoMapper, поэтому я могу проверить, имеет ли класс klass связанную модель assoc с одним или многими отношениями через

klass.associations[:assoc].is_a? MongoMapper::Plugins::Associations::OneAssociation
klass.associations[:assoc].is_a? MongoMapper::Plugins::Associations::ManyAssociation

но это кажется довольно неуклюжим и не является универсальным (т.е. не будет работать и для ActiveRecord ассоциаций). Я также хотел бы избежать загрузки каких-либо объектов, поэтому я почти уверен, что instance.assoc.is_a? Array тоже отсутствует.

Есть идеи?


person pariser    schedule 06.07.2013    source источник
comment
Вы когда-нибудь разбирались в этом? Я только что пришел, чтобы найти то же самое, но только для ActiveRecord   -  person MCB    schedule 22.11.2013


Ответы (1)


ОБНОВЛЕНИЕ: Итак, я наткнулся на методы класса Reflections http://api.rubyonrails.org/classes/ActiveRecord/Reflection/ClassMethods.html

Вы можете получить все has_many, belongs_to и т. д. с помощью метода reflect_on_all_associations. Это все там. Или вы можете ввести ассоциацию в reflect_on_association, и она сообщит вам, является ли это has_many, has_one и т. д. В частности:

Model.reflect_on_association(:assoc).macro

Этого должно быть достаточно для всех случаев. На самом деле это не решает проблему, над которой я сейчас работаю, но должно решить эту.

person MCB    schedule 21.11.2013
comment
Это не идеально, но может работать в зависимости от ваших имен классов. Рассмотрим класс User, который has_one принадлежит другому классу с именем UserAttributes. К сожалению, вы получите доступ к этому через user.user_attributes, который возвращает false на вызов respond_to?(assoc_name.singularize). Вы можете возразить (и, вероятно, будете правы), что вам следует переименовать этот класс в UserAttributeSet или что-то подобное, и в этом случае будет работать singularize, но нет никакой гарантии, что вы получите правильный тип ассоциации только потому, что имя экземпляра единственное или множественное число. - person pariser; 22.11.2013
comment
Ну, наличие имени модели во множественном числе противоречило бы соглашению об именах Rails (itsignals.cascadia.com.au /?p=7), поэтому у вас никогда не должно быть модели UserAttributes. Это всегда должен быть UserAttribute. Таким образом, единственное или множественное число должны отражать отношение has_one или has_many. Любые другие проблемы должны быть обработаны в любой логике, которая получает ввод для начала. - person MCB; 23.11.2013
comment
Действительно, вы правы - вот лучший способ продемонстрировать, что это не охватывает все случаи: рассмотрим модель Fish, в которой имя ассоциации "fish" является неисчисляемым. Это означает, что слово «рыба» является формой существительного как в единственном, так и во множественном числе (т. - person pariser; 04.12.2013
comment
Да, но это довольно уникальный случай. У вас есть это и олень, и я даже не могу придумать другой пример навскидку. И, как правило, я бы не назвал таблицу неправильным словом, которое является одним и тем же единственным или множественным числом, если только мне абсолютно не нужно было просто избегать крайних случаев. - person MCB; 05.12.2013