2011-05-12 6 views
0

私は、タグがタグ付けによって他のタグと接続されているモデルを持っています。特定のタグは、1つの親タグと複数の子タグを有することができる。 これは、Tag-モデルです:データベースからオブジェクトを取得する(高度な配列条件)

has_many :tagrelationships, :foreign_key => "parent_id", 
           :dependent => :destroy 
    has_many :children, :through => :tagrelationships, 
         :source => :child 

    has_one :reverse_tagrelationship, :foreign_key => "child_id", 
             :class_name => "Tagrelationship", 
             :dependent => :destroy 
    has_one :parent, :through => :reverse_tagrelationship, 
         :source => :parent 

Tagrelationship-モデル:

 belongs_to :child, :class_name => "Tag" 
     belongs_to :parent, :class_name => "Tag" 

データベース構造: tagrelationshipsが持っているupdated_atの、ID、名前、user_idは、はcreated_at: タグには、次の列を持っていますid、parent_id、child_id、created_at、updated_at

親タグを持たないタグを選択する方法が見つかりませんでした。もちろん、特定のユーザーのすべてのタグを選ぶと、ループ内でこれらを評価することで可能です:

@tags = Tag.where(:user_id => current_user) 

    @tags.each do |f| 
     if f.parent.nil? 
     @roottags << f 
     end 
    end 

配列@roottagsは、私が探している要素が含まれています。 1つのSQLクエリ内に親要素を持たないタグを選択する簡単な方法があると確信しています。

答えて

1

あなたの要件を満たす可能性のある代替提案があります。

別のリレーションシップクラスを作成する代わりに、parent_idをTagクラスに追加することで自己結合を実行することはどうでしょうか。

これは、次の方法で関係を簡素化:あなたはすべての親を持っていないタグ(すなわち、トップレベルのタグを)見つけたいとき

class Tag < ActiveRecord::Base 
    has_many :children, :class_name => "Tag", :foreign_key => "parent_id" 
    belongs_to :parent, :class_name => "Tag" 

    scope :top_level, where(:parent_id => nil) 
end 

は今、あなただけのことを名前付きスコープを使用することができます親IDを持つタグをフィルタリングします。

希望に役立ちます。

+0

「SQLite3 :: SQLException:いいえそのような列:tags.parent_id:SELECT COUNT(*)FROM "タグ" WHERE( "タグ"。 "parent_id" IS NULL) ' – tsoenke

+0

あなたの質問に一層良く対処するために私の答えを書きました。 – twmills

+0

もちろん、お勧めのソリューションは機能しますが、私はその関係を変更したくありません。クエリのためのより簡単な解決策が存在しない場合は、その質問に記載されているものに固執します。 – tsoenke

関連する問題