根据Sequel many_to_many关系中的连接表字段进行过滤

时间:2015-01-27 17:31:34

标签: ruby sequel

假设:

  • Sequel documentation的many_to_many部分中定义的many_to_many关联; artists --< albums_artists >-- albums
  • albums_artists有一个foo字段

如何访问albums_artists子句中WHERE表的字段?这种语法不起作用:

<% @artist.albums_dataset.where(:foo => 'bar').each do |album| %>
  ...
  <%= album[:foo] %>
  ...
<% end %>

如果我要为album_artists添加模型,在流程中创建两个关联,是否会删除现有的many_to_many关联?

1 个答案:

答案 0 :(得分:0)

您需要使用语法:tablename__columnname(两个下划线)qualify the table name获取要访问的列。

@artist.albums_dataset.filter(:albums_artists__foo => "bar").each do |album|

这是一个测试,也显示了生成的SQL:

require 'sequel'; DB = Sequel.sqlite
DB.create_table(:artists){ primary_key :id; String :name }
DB.create_table(:albums){ primary_key :id; String :name }
DB.create_table(:albums_artists) do
  String :foo
  foreign_key :artist_id, :artists
  foreign_key :album_id, :albums
  primary_key [:artist_id, :album_id]
end

class Artist < Sequel::Model; many_to_many :albums;  end
class Album  < Sequel::Model; many_to_many :artists; end

Artist.multi_insert [ {name:"Bob"}, {name:"Dylan"}, {name:"Joni"} ]
Album.multi_insert [ {name:"BobSolo"}, {name:"JoniSolo"},
                     {name:"BobJoni"}, {name:"BobDylan"},
                     {name:"BobJoniDylan"} ]

# If the album name includes the artist, add them to it.
Artist.each do |ar| Album.each do |al|
  if al.name.include?(ar.name)
    DB[:albums_artists] << {artist_id:ar.id, album_id:al.id}
  end
end end

bob.albums.map(&:name)
#=> ["BobSolo", "BobJoni", "BobDylan", "BobJoniDylan"]

bob.albums_dataset.filter(albums_artists__foo:"bar").sql
#=> SELECT `albums`.*
#=>   FROM `albums` INNER JOIN `albums_artists`
#=>   ON (`albums_artists`.`album_id` = `albums`.`id`)
#=>   WHERE ((`albums_artists`.`artist_id` = 1)
#=>     AND  (`albums_artists`.`foo` = 'bar'))

bob.albums_dataset.filter(albums_artists__foo:"bar").all
#=> [#<Album @values={:id=>5, :name=>"BobJoniDylan"}>]