2012-11-13 16 views
9

Zakładając, że koduję abstrakcję i przechodzę przez nazwy kolumn obiektu x, jaki jest najlepszy sposób na wykrycie, czy kolumna jest skojarzeniem czy nie?Rails/ActiveRecord: wykrywanie, czy kolumna jest powiązana, czy nie

wiem, że mogę to zrobić, ale zastanawiam się, czy istnieje lepszy sposób:

@user = User.first 
    @user.attributes.keys.each do |column| 
    if column[-3..-1] == "_id" && @user.respond_to?(column[0..-4].to_sym) 
     puts "#{column} is an association/relation." 
    else 
     puts "#{column} is not an assocation/relation." 
    end 
    end 
end 

Wszelkie metody lub pomocnicy wbudowane w szynach wykryć skojarzenia? Powyższy kod nie jest ani ładny, ani głupim dowodem. Dzięki!

Odpowiedz

15

Jednym ze sposobów, aby to zrobić byłoby zastanowić się nad wszystkimi stowarzyszeniami dla tej klasy:

associations = class_goes_here.reflect_on_all_associations 

A potem znaleźć tylko belongs_to te, ponieważ te będą miały pole _id:

associations = associations.select { |a| a.macro == :belongs_to } 

Następnie można znaleźć klucz obcy używany na tych skojarzeniach, wykonując to:

association_foreign_keys = associations.map(&:foreign_key) 

Nie użyłbym @user.attributes, aby uzyskać atrybuty, a następnie keys na tym, aby uzyskać nazwy kolumn. Chciałbym użyć User.column_names, aby uzyskać nazwy kolumn.

Dlatego, ze wszystkim, co wyjaśniono, można następnie zmienić swój kod za to aby uczynić go bardziej niezawodne:

associations = User.reflect_on_all_associations 
associations = associations.select { |a| a.macro == :belongs_to } 
association_foreign_keys = associations.map(&:foreign_key) 
User.column_names.each do |column| 
    if association_foreign_keys.include?(column) 
    puts "#{column} is an association/relation." 
    else 
    puts "#{column} is not an assocation/relation." 
    end 
end 
+0

Jak Rails 1.1.1 można filtrować przez makro natychmiast: 'stowarzyszenia = User.reflect_on_all_associations (: belongs_to) 'i zapisz drugą linię kodu. – ToniTornado

1

Jestem pewien, że wybrane rozwiązanie jest lepsze, ale jeśli mieszkasz w „idealnym świat”, gdzie każdy zgodnie z konwencją szynach, przypuszczam, można polegać na this:

2,2 Konwencje schematu Active Record wykorzystuje konwencje nazewnictwa dla kolumn w tabelach bazy danych, w zależności od cel tych kolumn.

Klucze obce - te pola powinny mieć nazwy zgodne ze wzorcem singularized_table_name_id (np. Item_id, order_id). Są to pola , których będzie szukał Rekord Aktywny podczas tworzenia skojarzeń między modelami.

Więc wystarczy spojrzeć na _id przyrostek na końcu nazwy kolumny:

Model.column_names.select{|cn| cn.include?("_id")} 
+0

Osobiście uważam, że jest to podejście podatne na błędy, ponieważ ludzie (niestety) łamią te zasady konwencji. –

+0

Dlatego wspomniałem o konwencjach. –

Powiązane problemy