1

我有一个允许用户在数据库中搜索项目的 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>

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

4

1 回答 1

2

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

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

包含选项基本上执行外连接而不是内连接。它还急切地加载记录,这意味着您将拥有“更大”的单个查询而不是多个查询。

这里有一个很好的解释

另请参阅此处

对于左连接,您可以执行以下操作:

if search_techs_ids.present?
  _projects = _projects.joins("LEFT OUTER JOIN technols ON technols.id = project.technol_id")
end
于 2012-10-10T08:52:41.923 回答