Question

I am implementing search and want to give the user the option to select multiple check boxes to search for those options. When multiple checkboxes are selected an AND operator will be used so all records which contain every option selected will be returned.

The code below works when one checkbox is selected, but it always returns 0 records when multiple checkboxes are selected. Can you please help.

Here is the code:

User.rb

  has_many :marketing_assets
  has_many :marketing_platforms, through: :marketing_assets

def self.has_platform(platform_object)
    where('marketing_platforms.name = ?', platform_object)

  end

  def self.search_for_platforms(platforms)
    @platforms = MarketingPlatform.all
    platforms_query_string = User
    platforms.each do |platform|
      @platforms.each do |platform_from_table|
        if platform == platform_from_table.name
          platforms_query_string = platforms_query_string.has_platform(platform_from_table.name)

        end
      end
    end
    return platforms_query_string
  end

experts_controller.erb

class ExpertsController < ApplicationController
  layout 'experts'

  def index


    @marketing_platforms = MarketingPlatform.all


    if params[:marketing_platforms_p].present?
      @users = User.joins(:marketing_platforms).search_for_platforms(params[:marketing_platforms_p])

      #@users = User.search_for_platforms(params[:marketing_platforms_p])
    else
      @users = User.text_search(params[:query]).page(params[:page]).per_page(10)

    end

  end
  def show
    @user = User.find(params[:id])
  end
end

experts.index.html.erb

<h1>Search</h1>

<%= params %>

<%= form_tag experts_path, method: :get do %>
    <p>
      <%= text_field_tag :query, params[:query] %>
    <hr>
    <h3>Marketing Assets</h3>

    <% MarketingPlatform.all.each do |platform| %>
        <%= check_box_tag "marketing_platforms_p[]", "#{platform.name}",
                          ((params[:marketing_platforms] != nil) && (params[:marketing_platforms].index(platform.name) != nil) ? true : false) %>
        <%= platform.name %>
    <% end %>


    <hr>
    <%= submit_tag 'Search', class: 'btn btn-primary', name: nil %>
    <%= link_to 'Find All', experts_path %>
    </p>
<% end %>


<h3>Results</h3>
<table class="table">
  <thead>
  <tr>
    <th>First name</th>
    <th>Last name</th>
    <th>Company</th>
    <th>Job title</th>
    <th>Country</th>
    <th>Email</th>
    <th></th>
  </tr>
  </thead>

  <tbody>
  <%= @users.count %>
  <% @users.each do |user| %>
      <tr>
        <td><%= user.first_name %></td>
        <td><%= user.last_name %></td>
        <td><%= user.company %></td>
        <td><%= user.job_title %></td>
        <td><%= user.country %></td>
        <td><%= user.email %></td>

        <td><%= link_to 'Show', expert_path(user) %></td>
      </tr>
  <% end %>
  </tbody>
</table>

The SQL that is being executed is

SELECT COUNT(*) FROM "users" INNER JOIN "marketing_assets" ON "marketing_assets"."user_id" = "users"."id" INNER JOIN "marketing_platforms" ON "marketing_platforms"."id" = "marketing_assets"."marketing_platform_id" WHERE (marketing_platforms.name = 'Google+') AND (marketing_platforms.name = 'Facebook')
Was it helpful?

Solution

I found the answer to this questions by reading the following question Select Multiple Values From Single Column

I wrote the following SQL:

SELECT "users".* 
FROM "users"  
WHERE "users"."id" 
IN (SELECT "users"."id" FROM "users"  
INNER JOIN marketing_assets ON users.id = marketing_assets.user_id 
WHERE  marketing_assets.marketing_platform_id= 3 
GROUP BY users.id HAVING COUNT(DISTINCT marketing_assets.marketing_platform_id) = 1)

I built the query object replacing all values with variables and then executed it using the find_by_sql Rails method:

@user = User.find_by_sql(**query**)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top