2011-10-11 135 views
1

我正在尝试为狮身人面像0.9.10和思维狮身人面像的我的Rails 3应用程序构建搜索功能。我希望用户搜索歌曲。我的歌可以有很多曲目。例如,歌曲“美丽的歌曲”,可以有一个音频链接到一个MP3,和一个视频轨道链接到YouTube。搜索has_many与Rails和思维狮身人面像的关系

现在,我的搜索功能运作良好时,我有相关的歌曲只有1条赛道,但越野车,当我有几条轨道...

我的用户应该能够输入关键字,并过滤以查找具有至少一个音频轨道,至少一个视频轨道或每个至少一个的歌曲。

到目前为止,我有我的歌以下模型:

class Song < ActiveRecord::Base 
    ... 
    has_many :tracks 
    ... 

    define_index('song') do 
    indexes        :name, 
              :sortable => :true 
    has  "tracks.media LIKE '%audio%'",:as   => :audio, 
              :type  => :boolean 
    has  "tracks.media LIKE '%video%'",:as   => :video, 
              :type  => :boolean 
    end 
end 

在我的跟踪模型中,我使用的是序列化媒体领域。 Ruby认为它是一个散列,其中包含一个链接和一个类型(例如'audio/m4u'或'video/mp4')。 MySQL将它视为一个字符串。

class Track < ActiveRecord::Base 
    belongs_to :Song 

    serialize :media 
end 

在我的歌控制器,我有这样的事情:

class CoursesController < ApplicationController 
    def search 
     with_params[:audio] = true if search[:audio] == true || search[:audio] == 'true' || search[:audio] == "1" 
     with_params[:video] = true if search[:video] == true || search[:video] == 'true' || search[:video] == "1" 

     @songs = Song.search(
     keywords, 
     :with  => with_params 
     ... 
    ) 
     ... 
    end 
end 

搜索结果都很好,当我有关联的歌曲只有一首曲目。

但是,当我有几个轨道,似乎搜索索引只看到第一首曲目:如果“美丽的歌曲”有第一个轨道“视频”,第二个“音频”,它只会显示在搜索结果如果我在我的过滤器中选择“视频”,如果选择“音频”则不显示。

我错过了什么?

回答

2

您需要做的是与媒体列的连接值进行比较。在MySQL中,那将是这个样子:

GROUP_CONCAT(`tracks`.`media` SEPARATOR ' ') 

或者对PostgreSQL(使用8.4或更好 - 让我知道,如果你使用的是旧版本):

array_to_string(array_agg("tracks"."media"), ' ') 
+0

感谢帕特!我将如何做一个OR语句而不是AND? (现在,如果我同时检查“音频”和“视频”,它会返回具有音频和视频轨道的歌曲,但我希望具有音频和/或视频轨道的歌曲) – alex

+0

我只需添加另一个属性即可检查连接结果是LIKE无论是视频还是音频。虽然有一个纯粹的狮身人面像方法:http://freelancing-god.github.com/ts/en/common_issues.html#or_attributes – pat

+0

完美!我创建了一个新的属性......它适合我当前的代码。 – alex