I am happy to announce that StrokeDB got an experimental has_many support recently.
Now you can easily collect documents that refer to your document by defining has_many for your meta:
(All examples shown are done in test/console)
Playlist = Meta.new do
has_many :songs
end
==>Playlist
Song = Meta.new
==>Song
playlist = Playlist.create!(:name => "My playlist")
==>#<Playlist name: "My playlist", __version__: 330f...>
song = Song.create!(:name => "My song", :playlist => playlist)
==>#<Song name: "My song", __version__: 530f..., playlist: #<Playlist name: "My playlist", __version__: 330f...>>
playlist.songs
==>[#<Song name: "My song", __version__: 530f..., playlist: #<Playlist name: "My playlist", __version__: 330f...>>]
So, here we define has_many :songs, which inflates :songs to Song meta and uses Song’s :playlist slot as a reference to Playlist. Like in ActiveRecord, this definition uses configuration by convention. And again, like in ActiveRecord, you can tweak it:
Playlist = Meta.new do
has_many :all_songs, :through => :songs, :foreign_reference => :belongs_to_playlist
end
==>Playlist
Song = Meta.new
==>Song
playlist = Playlist.create!(:name => "My playlist")
==>#<Playlist name: "My playlist", __version__: 3245...>
song = Song.create!(:name => "My song", :belongs_to_playlist => playlist)
==>#<Song name: "My song", __version__: 5245..., belongs_to_playlist: #<Playlist name: "My playlist", __version__: 3245...>>
playlist.all_songs
==>[#<Song name: "My song", __version__: 5245..., belongs_to_playlist: #<Playlist name: "My playlist", __version__: 3245...>>]
Here we use :through option which tells StrokeDB to use Song meta to find documents, and :foreign_reference specifies Song’s slot name for the reference to Playlist. You can also add some conditions to has_many:
Playlist = Meta.new do
has_many :rock_songs, :through => :songs, :foreign_reference => :belongs_to_playlist, :conditions => {:genre => "Rock"}
end
==>Playlist
Song = Meta.new
==>Song
playlist = Playlist.create!(:name => "My playlist")
==>#<Playlist name: "My playlist", __version__: 3cd6...>
rock_song = Song.create!(:name => "My song", :belongs_to_playlist => playlist, :genre => "Rock")
==>#<Song name: "My song", __version__: 5cd6..., belongs_to_playlist: #<Playlist name: "My playlist", __version__: 3cd6...>, genre: "Rock">
pop_song = Song.create!(:name => "My song 2", :belongs_to_playlist => playlist, :genre => "Pop")
==>#<Song name: "My song 2", __version__: 6cd6..., belongs_to_playlist: #<Playlist name: "My playlist", __version__: 3cd6...>, genre: "Pop">
playlist.rock_songs
==>[#<Song name: "My song", __version__: 5cd6..., belongs_to_playlist: #<Playlist name: "My playlist", __version__: 3cd6...>, genre: "Rock">]
Isn’t it nice? But lets go further. What if you want to know all authors of music in your playlist? That’s quite simple!
Playlist = Meta.new do
has_many :authors, :through => [:songs, :author]
end
==>Playlist
Song = Meta.new
==>Song
playlist = Playlist.create!(:name => "My playlist")
==>#<Playlist name: "My playlist", __version__: 3903...>
song = Song.create!(:name => "My song", :playlist => playlist, :author => "John Doe")
==>#<Song name: "My song", __version__: 5903..., author: "John Doe", playlist: #<Playlist name: "My playlist", __version__: 3903...>>
playlist.authors
==>["John Doe"]
or
Playlist = Meta.new do
has_many :authors, :through => [:songs, :author]
end
==>Playlist
Song = Meta.new
==>Song
Author = Meta.new
==>Author
playlist = Playlist.create!(:name => "My playlist")
==>#<Playlist name: "My playlist", __version__: 3b19...>
author = Author.create!(:name => "John Doe")
==>#<Author name: "John Doe", __version__: 5b19...>
song = Song.create!(:name => "My song", :playlist => playlist, :author => author)
==>#<Song name: "My song", __version__: 7b19..., author: #<Author name: "John Doe", __version__: 5b19...>, playlist: #<Playlist name: "My playlist", __version__: 3b19...>>
playlist.authors
==>[#<Author name: "John Doe", __version__: 5b19...>]
So here in these examples has_meta fetches all Songs and gets all their :author slots.
So here it is. Current has_many implementation is quite experimental and might change later (for example, we’re still thinking about improving :conditions stuff for :through => [...] case, since :conditions are currently applying only to Songs). And most probably it has some bugs :)




