Adear
Adear

Reputation: 2125

Rails filtering has and belongs to many databases

i have a user table that has and belongs to many tools.

so each user can have as many tools as they want and the tools can be associated with the user.

what i am trying to do is create a filter system so that on my main page people can click a selection of tools and it will show only users that have an association with those tools.

so it needs to brings back only users that have all of the skills someone has selected for instance someone who has Git and Jira , Not git or Jira

i can do it for one tool by using

if params["Confluence"]
        contractors = contractors.includes(:tools).where(tools: { name: "Confluence" })
end

i have tryed doing something like this

contractors = contractors.includes(:tools).where(tools: { name: "Confluence" , name: "Git", name: "JIRA Core" , name:"JIRA Software"})

but it only brings back the users with the last tool in the list. i have also tryed like this

    if params["JIRA Core"]
        contractors = contractors.includes(:tools).where( tools: {name: "JIRA Core"})
    end

    if params["JIRA Software"]
        contractors = contractors.includes(:tools).where( tools: {name: "JIRA Software"})
    end

however this does not work either. anyone have any ideas?

Upvotes: 0

Views: 80

Answers (2)

Vishal G
Vishal G

Reputation: 1541

Check this out

This is the case when you need contractors should at least one of the tools

contractors.joins(:tools).where('tools.name IN (?) ', ['JIRA Core','Git']).uniq

OR 

contractors.joins(:tools).where('tools.name = ?', "JIRA Core").uniq

OR

This is the case when you need contractors should have all the tools

param_values = ['JIRA Core','Git']

contractors.joins(:tools).where('tools.name IN (?) ', param_values).group('contractors.id').having('contractors.count = ?', param_values.count).uniq

Upvotes: 1

Shaik Azeez Ahmed
Shaik Azeez Ahmed

Reputation: 1

Your params of tools should be the array of tools that are selected by the user

@tools = params[:tools]

Declare contractors array to which you will push by querying for each tool

@contractors = []

@tools.each do |tool|
  @contractors << Contractor.includes(:tool).where(tools: {name: tool.name})
end

and flatten to do .each in the view templates.

@contractors.flatten!

in Views:

<% @contractors.each do |contractor|%>
  <p><%=contractor.name</p>
<%end%>

Upvotes: 0

Related Questions