问题
I had a problem where I was getting duplicate results in a search, in my rails app that allow the user to search for projects in a database.
Here is the search function in the project model:
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.includes(:technols).where("technols.id" => search_techs_ids)
end
_projects
end
and here is part of my search page
<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>
Here is my search action:
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
That problem is now sorted, but in fixing that, I noticed that when I search for a single technology, the correct projects show up in the table, but in the technology column it is meant to show all the technologies belonging to that project but it only shows the one I searched for:
<% @project_search.each do |t| %>
<tr>
<td><ul>
<% t.technols.each do |technol| %>
<li><%= technol.tech %><!/li>
<% end %>
</ul></td>
Any ideas? In my model I used to have this code which worked for displaying the table correctly, but showed duplicate results.
if search_techs_ids.present?
_projects = _projects.joins(:technols).where("technols.id" => search_techs_ids)
end
Any help at all will be appreciated. Thanks in advance
SOLUTION see answers below
@shioyama and @tommasop both helped fix the problem.
The solution was to change my search view where the column is made to
<td><ul>
<% t.technols(force_reload=true).each do |technol| %>
<li><%= technol.tech %></li>
<% end %>
</ul></td>
回答1:
I encountered the same problem in a different guise: Matching nested model association attribute with includes
See also this discussion on the globalize3 github issue page, where the problem came up when trying to destroy a record after searching by dynamic finder (leaving unmatched associations behind in the DB).
The problem is that you're restricting the join to projects with given technology associations (those with id
s in search_tech_ids
), so those are the only rows that rails returns. Rails has no way of knowing there are others there.
Basically so far as I can tell, the easiest solution is just to reload the projects after completing the search. Add a line just above the last line of your search
method, like so:
_projects.each { |p| p.technols.reload }
_projects
This will tell rails to reload the technologies associated with each project, including the technologies it did not match in the search. I believe that should work in your case.
UPDATE:
After many attempts (see comments) and a suggestion from @tommasop, the solution was to force-reload the technologies in the view with:
t.technols(force_reload=true).each
Still not clear why the reload approach above wasn't working. If anyone has any insights please let me know, I'd be curious to hear.
回答2:
Try with this syntax:
_projects.each { |p| p.technols(force_reload=true) }
_projects
reference here.
来源:https://stackoverflow.com/questions/12817954/ruby-on-rails-after-search-list-not-displaying-all-data