在Rails 3中进行以下连接的最佳方式

时间:2011-06-20 23:23:11

标签: ruby-on-rails ruby-on-rails-3

我有以下课程:

class Annotation < ActiveRecord::Base
  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

以及以下加入:

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

在Rails 3中编写代码的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

您有两种选择:

使用has_many,:xs,:through =&gt; :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

然后你可以输入:

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

或者,如果您在AnnotationTag模型上不需要额外的属性,即它纯粹是一个连接表,则可以使用has_and_belongs_to_many。您的联接表不得包含id列,因此在迁移过程中,请确保指定:id =&gt;如the ActiveRecord Associations API docs

中所述,为false
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

在这种情况下,获取标记的所有注释的语法是相同的。

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

答案 1 :(得分:0)

这是我最初的尝试:

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是一个更清晰的解决方案,但确实要求我的连接表类名更改为AnnotationsTags(注意复数)。