如何在rails中编写多对多基数的查询

时间:2010-12-06 10:00:57

标签: ruby-on-rails

嘿伙计们 我是rails的新手,对我来说有很多让人大开眼界的事情,而且我写了一些代码并且看起来效率不高,我在下面粘贴代码,你能不能帮我找到更好的方法来编写代码。

视频表:

class CreateVideos < ActiveRecord::Migration
  def self.up
    create_table :videos do |t|
      t.string :title
      t.string :desc
      t.string :tudou
      t.string :otherurl

      t.timestamps
    end
  end

  def self.down
    drop_table :videos
  end
end
鼓手表:

class CreateDrummers < ActiveRecord::Migration
  def self.up
    create_table :drummers do |t|
      t.string :first_name
      t.string :middle_name
      t.string :last_name
      t.string :nick_name
      t.boolean :gender

      t.timestamps
    end
  end

  def self.down
    drop_table :drummers
  end
end

我将它们设置为简单的多对多关联

class CreateDrummersVideosJoin < ActiveRecord::Migration
  def self.up
    create_table :drummers_videos, :id => false do |t|
    t.integer "drummer_id" 
    t.integer "video_id"
    end
  end


  def self.down
    drop_table :drummers_videos
  end
end

我想找到鼓手名字的所有标题是“Jojo”姓氏是“Mayer”的视频

我的代码:

title = Drummer.where(:first_name => "Jojo", :last_name => "Mayer").first.videos.each {|t| t.title}

这将返回所有列的数据,而不是唯一的我想要的标题

并且由于只有一个结果返回名为“Jojo Mayer”,但返回值为activeRelation,我无法调用视频,因此我的工作是使用:首先获取视频实例以便调用视频。我知道这绝对不是这样做的方式

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您需要在它们之间使用连接表,就像您推断的那样。但是,不必在迁移中创建Rails中的连接表。它可以在模型中完成。

#drummer.rb
 belongs_to  :drummer_videos, :polymorphic => true
 has_many    :videos, :as => :drummer_videos

#video.rb
 belongs_to :drummer_videos, :polymorphic => true
 has_many :drummers, :as => :drummer_videos

确保drummer TABLEvideo TABLE具有drummer_videos_id属性。

然后你可以打电话给你的鼓手..

Drummer.where(:first_name => "Jojo", :last_name => "Mayer").videos.each {|t| t.title}

答案 1 :(得分:1)

首先,如果你只想从视频中获取title属性,你应该使用map或collect而不是每个,所以像这样:

Drummer.where(...).first.videos.map{ |t| t.title }

甚至更短:

.map(&:title)

其次,在我看来,如果你真的想要从一个Drummer对象中获取所有视频,而不是像你那样以某种方式使用第一个视频,这是一个非常好的选择。

否则,如果您想根据特定标准获取来自不同鼓手的所有视频,那么您应该直接拨打视频,然后加入或加入鼓手。也许是这样的:

Video.joins(:drummers).where("drummers.first_name = 'jojo' AND drummers.last_name = 'Mayer'").map(&:title)