10

コードを抽象化し、オブジェクトxの列名をループしているとすると、列が関連付けであるかどうかを検出するための最良の方法は何ですか?

私はこれができることを知っていますが、もっと良い方法があるかどうか疑問に思っています:

@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メソッドまたはヘルパーはありますか?上記のコードは、きれいでもばかげた証拠でもありません。ありがとう!

4

2 に答える 2

19

これを行う1つの方法は、そのクラスのすべての関連付けを反映することです。

associations = class_goes_here.reflect_on_all_associations

そして、それらがフィールドbelongs_toを持っているので、それらだけを見つけるために_id

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
于 2012-11-13T04:30:32.887 に答える
1

選択したソリューションの方が優れていると確信していますが、誰もがレールの慣習に従う「理想的な世界」に住んでいる場合は、これに頼ることができると思います。

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

外部キー-これらのフィールドには、パターンsingularized_table_name_id(item_id、order_idなど)に従って名前を付ける必要があります。これらは、モデル間に関連付けを作成するときにActiveRecordが検索するフィールドです。

したがって、列名の最後にある_idサフィックスを探してください。

Model.column_names.select{|cn| cn.include?("_id")}
于 2015-08-07T13:28:55.270 に答える