2012-11-13 4 views
9

コードを抽象化し、オブジェクトxの列名をループしていると仮定して、列が関連しているかどうかを検出する最良の方法は何ですか?Rails/ActiveRecord:列が関連しているかどうかを検出

私はこれを行うことができます知っているが、より良い方法がある場合、私は疑問に思って:

@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 

どれビルトインRailsのメソッドやヘルパーの関連付けを検出するには?上記のコードは、あまりにも偽証でもありません。ありがとう!

associations = class_goes_here.reflect_on_all_associations 

そしてそれらが_idフィールドを持つことになりますから、ちょうどbelongs_toものを見つけるために:これを行うには

答えて

15

一つの方法は、そのクラスのすべての関連付け時に反映させることであろう

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

これを実行すると、これらの関連付けで使用される外部キーを見つけることができます。

association_foreign_keys = associations.map(&:foreign_key) 

属性を取得するのに@user.attributesを使用せず、列名を取得するにはkeysを使用しません。私はUser.column_namesを使用して列名を取得します。

したがって、説明したすべてで、あなたは、このことが、より確実な作るためになるようにコードを変更することができます。

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

のRailsのとおり、マクロすぐでフィルタリングすることができます: 'アソシエーション=のUser.reflect_on_all_associations(:belongs_toの) 'コードの2行目を保存します。 – ToniTornado

1

私が選択したソリューションが優れていることを確信している、しかし、あなたは理想的「に住んでいる場合世界」、誰もがレールの規則に従うところ、私はあなたがthisに頼ることができるとします

2.2スキーマの表記Active Recordはに応じて、データベーステーブル内 の列の命名規則を使用していますこれらの列の目的。

外部キー - これらのフィールドの名前は、パターン singularized_table_name_id(item_id、order_idなど)の名前に基づいて指定する必要があります。これらのフィールドは、 というフィールドがあり、アライメントをモデル間で作成するときにアクティブレコードが検索します。

だから、列名の末尾に_id接尾辞を探し:1.1.1

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

私は個人的には(あいにく)人々がそれらの大会の規則を破るので、エラーが起こりやすい方法だと思っています。 –

+0

だからこそ私は慣習を述べました。 –

関連する問題