我有一个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>
这用于显示该项目的所有技术列表,但现在使用新代码,它只显示我搜索的那个。有什么想法吗?
答案 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