2013-10-23 56 views
5

我想要获取所有主题名称将与搜索关键字匹配的配置文件。现在我正在加载所有配置文件。我需要知道我该如何实现它。任何帮助深表感谢。如何通过导轨中的关联进行搜索4

Profile.rb

has_many :categorizations 
has_many :subjects, through: :categorizations 

subject.rb中

has_many :categorizations 
has_many :profiles, through: :categorizations 

Categorization.rb

belongs_to :profile 
belongs_to :subject 

意见/搜索/ index.html.erb

# search form 
<%= form_tag search_index_path, :method => 'get' do %> 
    <%= text_field_tag :search, params[:search] %> 
    <%= submit_tag "search", :name => nil %> 
<% end %> 

# search results 
<% @profiles.each do |profile| %> 
    <%= profile.name %> 
<% end %> 

search_controller.rb

def index 
    @profiles = Profile.with_translations('en').all 
end 
+1

你需要搜索的关键字精确匹配的轮廓主题? – Teddy

+0

不完全相同,如果主题名称上的词匹配比静态配置文件应显示在搜索结果中。 – Murtza

回答

4

需要补充的是使用Rails的想法full text searching。如果你执行搜索,你需要知道,你实际在您的数据库,根据不同的SQL引擎,它是不同的全文“搜索”查询您使用


MYSQL全文搜索

LIKE %{search}%机制是MYSQL的非常基本的全文搜索功能,并且基本上在您的数据库中查找整个记录内的目标查询。这意味着,如果您的查询是这样的:

SELECT * FROM `products` WHERE `name` LIKE '%alligator%' 

MYSQL将基本贯穿整个“名”的记录查找任何引用到您的查询。结果将取决于您的记录是否在其任何部分都有“鳄鱼”一词。 This reference解释了更多关于这


PostgreSQL的全文搜索

我写这篇文章是因为PSQL实际做法与此不同,因此,你已经提供查询将只限于MySQL工作的原因。PSQL有很多不同的功能来处理全文搜索,但由于我们使用Heroku的,我们成功地使用Textacular gem把一切工作正常

这里有some ways PSQL handles full text searching

Full text searching in PostgreSQL is based on the match operator @@, which returns true if a tsvector (document) matches a tsquery (query). It doesn't matter which data type is written first:

SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat & 
rat'::tsquery; ?column? 
---------- t 

SELECT 'fat & cow'::tsquery @@ 'a fat cat sat on a mat and ate a fat 
rat'::tsvector; ?column? 
---------- f 

As the above example suggests, a tsquery is not just raw text, any more than a tsvector > is. A tsquery contains search terms, which must be already-normalized lexemes, and may combine multiple terms using AND, OR, and NOT operators. (For details see Section 8.11.) There are functions to_tsquery and plainto_tsquery that are helpful in converting user-written text into a proper tsquery, for example by normalizing words appearing in the text. Similarly, to_tsvector is used to parse and normalize a document string. So in practice a text search match would look more like this:

SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat'); ?column? 
---------- t Observe that this match would not succeed if written as 

SELECT 'fat cats ate fat rats'::tsvector @@ to_tsquery('fat & rat'); ?column? ---------- f


全文搜索软件

全文搜索在数据库中本质上相当昂贵,特别是如果您有大量数据要搜索时。这就是为什么像sunspot solrsphinx解决方案存在 - 提供了一种既指标&搜索数据,你有

如果您的应用程序变得非常流行,你不妨投入到全文检索系统之一,如these demonstrated by Heroku

Heroku's full text search packages

+0

非常感谢你提供了这样详细的答案,但实际上我是新的以轨道和试图了解如何通过关联进行搜索,但我已经找到了你的答案作为一个好的选择,让我试试它在一个新的应用程序。我通过看Ryan的railscast尝试着太阳黑子。 – Murtza

+2

没问题!如果你刚接触rails,我实际上不会推荐实现“hardcore”全文搜索的东西(它需要一些工作才能使它工作)。我想要做的是给你一个你实际想要做什么的定义;而不是你只是得到一个查询,你将有一个功能集准备实施,当你抛光你的技能:) –

+1

经过几天的练习,我成功地使用了太阳黑子宝石。感谢您的指导。我有一个问题,我可以使用全球化宝石的太阳黑子吗? – Murtza

4
@profiles = Subject.where("name LIKE ?", "%#{params[:search]}%").map(&:profiles) 
+1

我得到以下结果“Mysql2 ::错误:'字段列表'中的未知列'profile_id':SELECT profile_id FROM'subjects' WHERE(name LIKE'%%')” – Murtza

+0

@Murtza更新了我的答案。 – x3qt

+0

现在我得到“未定义的方法'model_name'为”,它不会在结果中打印profile.name。 – Murtza

2

检查,如果这个工程。

@profiles = Profile.joins(:subjects).where("subject.name like '%?%'",params[:search]) 
+0

不,它不工作,并给我错误以下错误“Mysql2 ::错误:您的SQL语法中有错误;检查手册,对应于您的MySQL服务器版本的正确语法使用附近'%''%)'第1行:SELECT'profiles'。* FROM'profiles' INNER JOIN'categorizations' ON'categorizations'.'profile_id' ='profiles'.'id' INNER JOIN'subjects' ON'subjects'.'id' ='分类'.'subject_id'其中(主题名称如%''%)“ – Murtza

+1

@Murtza编辑。用您的搜索查询替换'params [:search]' – shiva

+0

我用关键字“数学”取代了它,但它仍然显示相同的错误。 – Murtza