0

I have a model, in which Tags are connected with other Tags through Tagrelationships. A certain Tag may have one parent-Tag and several child-Tags. This is the Tag-model:

    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

The Tagrelationship-model:

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

The database structure: tags have the following columns: id, name, user_id, created_at, updated_at tagrelationships have the columns: id, parent_id, child_id, created_at, updated_at

I couldn't find out how to pick the Tags which haven't got any parent-Tags. Of course it's possible by picking all Tags of a certain user and evaluating these in a loop:

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

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

The array @roottags contains the elements I'm looking for. I'm sure there's an easier way to pick the tags without any parent-elements within one sql-query.

1 Answer 1

1

Here's an alternative suggestion that may meet your requirements.

Instead of creating a separate relationship class, what about performing a self-join by adding a parent_id to the Tag class.

This simplifies the relationships in the following ways:

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

Now when you want to find the Tags that don't have any parents (i.e. top level tags), you can just use the named scope that filters tags that have parent ID's.

Hope that helps.

Sign up to request clarification or add additional context in comments.

3 Comments

In both cases I get the following error-message: 'SQLite3::SQLException: no such column: tags.parent_id: SELECT COUNT(*) FROM "tags" WHERE ("tags"."parent_id" IS NULL)'
I rewrote my answer to better address your question.
Of course your recommended solution works, but I don't want to change the relationship. If there doesn't exist a simpler solution for the query I would stick to the one described in the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.