Ruby on Rails:搜索时重复的结果

时间:2012-10-10 08:34:14

标签: ruby-on-rails ruby search model controller

我有一个rails应用程序,允许用户在数据库中搜索项目。

以下是项目模型中的搜索功能:

def self.search(search_industry, search_role, search_techs_ids)

    _projects = Project.scoped 

    if search_industry.present?
      _projects = _projects.where ['industry LIKE ?', like(search_industry)]
    end
    if search_role.present?
      _projects = _projects.where ['role LIKE ?', like(search_role)]
    end
    if search_techs_ids.present?
    _projects = _projects.joins(:technols).where("technols.id" => search_techs_ids)
    end
    _projects
    end

这是我的搜索页面的一部分

<div class="tech">
<%= fields_for(@project_technol) do |ab| %>
 Technologies : 
 <%     tech_ids = params[:technols][:id].reject(&:blank?) unless params[:technols].nil? %>

<%if params[:technols].nil?%>

<%= collection_select(:technols, :id, @all_technols, :id, :tech, {}, {:multiple => true} ) %>

<% else %>

<%= collection_select(:technols, :id, @all_technols, :id, :tech, {}, {:multiple => true, :selected => tech_ids } ) %>
<% end %>

</div>

以下是我的搜索操作:

def search

    tech_ids = params[:technols][:id].reject(&:blank?) unless params[:technols].nil?

    @search =  params[:industry], params[:role], tech_ids

    @project_search = Project.search(*@search).order(sort_column + ' ' + sort_direction).paginated_for_index(per_page, page)

    @search_performed = !@search.reject! { |c| c.blank? }.empty? 

  @project = Project.new(params[:project])

    @all_technols = Technol.all

    @project_technol = @project.projecttechnols.build

respond_to do |format|
      format.html # search.html.erb
      format.json { render :json => @project }
    end

end

我的问题是,当我在搜索页面上的collection_select中选择所有技术并单击搜索时,结果似乎显示所有记录的重复项,如果它们包含多种技术。

例如,数据库中有3个项目。 P1,P2,P3和都有3种技术,T1,T2和T3。如果我要搜索所有3种技术,每个项目都应该出现一次,但相反,它们会显示3次。

有没有人有任何想法我可能会出错。提前谢谢。

修改

搜索时我的参数:

Parameters: {"utf8"=>"✓", "client"=>"", "industry"=>"", "technols"=>{"id"=>["", "40", "41", "42", "43", "44", "46", "47", "48", "49", "50", "51", "52", "53", "54"]}, "start_date_dd"=>"", "start_date_A"=>"", "start_date_B"=>"", "status"=>"", "per_page"=>"10"}
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  Technol Load (0.3ms)  SELECT "technols".* FROM "technols" 
  Project Load (0.8ms)  SELECT "projects".* FROM "projects" ORDER BY client
  Project Load (0.4ms)  SELECT "projects".* FROM "projects" ORDER BY industry
  Project Load (0.4ms)  SELECT "projects".* FROM "projects" ORDER BY status
   (1.0ms)  SELECT DISTINCT COUNT(*) FROM "projects" INNER JOIN "projecttechnols" ON "projecttechnols"."project_id" = "projects"."id" INNER JOIN "technols" ON "technols"."id" = "projecttechnols"."technol_id" WHERE "technols"."id" IN (40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54)
  Project Load (13.2ms)  SELECT DISTINCT "projects".* FROM "projects" INNER JOIN "projecttechnols" ON "projecttechnols"."project_id" = "projects"."id" INNER JOIN "technols" ON "technols"."id" = "projecttechnols"."technol_id" WHERE "technols"."id" IN (40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54) ORDER BY project_name asc LIMIT 10 OFFSET 0
  Technol Load (0.9ms)  SELECT "technols".* FROM "technols" INNER JOIN "projecttechnols" ON "technols"."id" = "projecttechnols"."technol_id" WHERE "projecttechnols"."project_id" = 107
  Technol Load (1.8ms)  SELECT "technols".* FROM "technols" INNER JOIN "projecttechnols" ON "technols"."id" = "projecttechnols"."technol_id" WHERE "projecttechnols"."project_id" = 100
  Technol Load (1.8ms)  SELECT "technols".* FROM "technols" INNER JOIN "projecttechnols" ON "technols"."id" = "projecttechnols"."technol_id" WHERE "projecttechnols"."project_id" = 106
  Rendered projects/search.html.erb within layouts/application (68.2ms)
Completed 200 OK in 100ms (Views: 74.8ms | ActiveRecord: 22.8ms)

更新

我刚发现一个错误。

我的模型现在包含此代码;

if search_techs_ids.present?
  _projects = _projects.includes(:technols).where("technols.id" => search_techs_ids)
end

其中不再显示重复项,但是当我在显示结果的表中搜索单个技术时,我注意到了。我有这个专栏:

<td><ul>
  <% t.technols.each do |technol| %>
    <li><%= technol.tech %><!/li>
  <% end %>
</ul></td>

这用于显示该项目的所有技术列表,但现在使用新代码,它只显示我搜索的那个。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您可以尝试使用包含而不是连接吗?

if search_techs_ids.present?
  _projects = _projects.includes(:technols).where("technols.id" => search_techs_ids)
end

include选项基本上是外连接而不是内连接。它也渴望加载记录,这意味着你将有一个“更大”的单个查询而不是多个查询。

请参阅here以获得更好的解释

另见here

对于左连接,您可以按照以下方式执行操作:

if search_techs_ids.present?
  _projects = _projects.joins("LEFT OUTER JOIN technols ON technols.id = project.technol_id")
end