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つのテクノロジーすべてを検索すると、すべてのプロジェクトが1回表示されますが、代わりに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

includeオプションは、基本的に、内部結合ではなく外部結合を実行します。また、レコードを熱心にロードします。これは、複数のクエリではなく、「より大きな」単一のクエリがあることを意味します。

良い説明についてはここを参照してください

こちらもご覧ください

左結合の場合、次の線に沿って何かを行うことができます。

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 に答える