开发者

Best way to do the following join in Rails 3

I have the following classes:

class Annotation < ActiveRecord::Ba开发者_运维问答se
  has_many :annotation_tags
end

class Tag < ActiveRecord::Base
  has_many :annotation_tags
end

class AnnotationTag < ActiveRecord::Base
  belongs_to :annotation
  belongs_to :tag
end

and the following join:

SELECT `annotations`.*, annotation_tags.* FROM `annotations` JOIN annotation_tags on
    annotation_tags.annotation_id =  annotations.id and annotation_tags.tag_id = 123

What is the best way to code this in Rails 3?


You have two options:

Use has_many, :xs, :through => :ys.

class Annotation < ActiveRecord::Base
  has_many :annotation_tags
  has_many :tags, :through => :annotation_tags
end

class Tag < ActiveRecord::Base
  has_many :annotation_tags
  has_many :annotations, :through => :annotation_tags
end

class AnnotationTag < ActiveRecord::Base
  belongs_to :annotation
  belongs_to :tag
end

Then you can type:

tag = Tag.find(123)
annotations = tag.annotations

Alternatively, if you don't need extra attributes on your AnnotationTag model, i.e. it's purely a join table, you can use has_and_belongs_to_many. Your join table must not have an id column, so in the migration, make sure you specify :id => false as described in the ActiveRecord Associations API docs

class Annotation < ActiveRecord::Base
  has_and_belongs_to_many :tags
end

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :annotations
end

class AnnotationsTag < ActiveRecord::Base # First part of model name must be pluralized.
  belongs_to :annotation
  belongs_to :tag
end

In this case the syntax for getting all the annotations for a tag is the same.

tag = Tag.find(123)
annotations = tag.annotations


Here was my initial attempt:

tag_id = 123
Annotation.joins("JOIN #{AnnotationTag.table_name} on #{AnnotationTag.table_name}.annotation_id =  #{Annotation.table_name}.id and #{AnnotationTag.table_name}.tag_id = #{tag_id}").scoped

@Cameron's is a much cleaner solution, but did require my join table class name to be changed to AnnotationsTags (note the plural).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜