如何在rails4上使用join来选择ruby中的多对多关系模型?

时间:2015-11-23 03:36:56

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

我的数据模型是研究员,笔记和标签的关系是多对多

class Note < ActiveRecord::Base

  attr_accessible :title
  attr_accessible :content
  attr_accessible :created_at
  default_scope -> { order(created_at: :desc) }

  has_and_belongs_to_many :hashtags
end

class Hashtag < ActiveRecord::Base
  attr_accessible :name
  has_and_belongs_to_many :notes
end

class NoteHashtag < ActiveRecord::Base
  t.belongs_to :note, index: true
  t.belongs_to :hashtag, index: true
end

我想查询sql,如:

 select Note.* from Note inner join NoteHashtag on Note.id=NoteHashtag.note inner join Hashtag on NoteHastag.hashtag=Hashtag.id where Hashtag.name="test"

如何将sql转换为rails4上的ruby中的datamodel操作?

我尝试使用:

@note=Note.joins(:hashtag).where(name: "test")

,错误是:

ActionView::Template::Error (Association named 'hashtag' was not found on Note;perhaps you misspelled it?):

3 个答案:

答案 0 :(得分:1)

如果要明确定义连接模型has_many :through,则需要NoteHashtag个关联。如果删除该模型,则可以执行@notes=Note.joins(:hashtag).where(name: "test"),ActiveRecord将生成您期望的查询。

否则你可以做

class Note < ActiveRecord::Base
  ...
  has_many :note_hashtags
  has_many :hashtags, through: :note_hash_tags
end

class Hashtag < ActiveRecord::Base
  attr_accessible :name
end

class NoteHashtag < ActiveRecord::Base
  belongs_to :note
end

然后@notes = Note.joins(:note_hashtags).joins(:hash_tags).where(name: "test)就可以了。

请注意,这两项都会返回多个note

答案 1 :(得分:0)

您可以通过以下方式获取多对多关系的记录: -

@note = Note.joins(:hashtags).where('hashtags.name' => 'test')

答案 2 :(得分:0)

为什么不解决源于正确模型的这种关系?像这样定义你的模型:

class Note < ActiveRecord::Base
  ...
  has_many :note_hashtags
  has_many :hashtags, through: :note_hashtags
end

class Hashtag < ActiveRecord::Base
  attr_accessible :name
  has_many :note_hashtags
  has_many :notes through: :notes_hashtags
end

class NoteHashtag < ActiveRecord::Base
  belongs_to :note
  belongs_to :hashtag
end

然后像这样查询:

Hashtag.where(name: 'Test').notes