John John - 5 months ago 15
Ruby Question

Rails search function rendering page multiple timess

I have a search function in rails that should render a page to display the grants that were picked up by the search. However when you search, the template is rendered multiple times instead of just once, and its rendered on top of itself so it looks like a cluttered mess. I'm not sure where the error is but it must be calling render more than once. Heres my controller method:

def index
if params[:search]
@grants = Grant.search(params[:search]).order("created_at DESC")
else
@grants = Grant.all.order('created_at DESC')
end

end


And the part of my view where I render the template

<% if @grants.present? %>
<%= render @grants %>
<% else %>
<p>There are no grants containing the term(s) <%= params[:search] %>.</p>
<% end %>
<%= yield %>


and the template;

<html>
<body>
<style>div {
margin-left:17%;
padding:1px 16px;
height:1000px;}
</style>
<div>
<center>
<hr style="height:5 px; visibility:hidden;" />
<br>
<font size=6 >
<strong>
<A HREF="/" STYLE="text-decoration: none; color: black">US Federal Grants</a>
<br>
<br>
<hr style="height:5 px; visibility:hidden;" />
</strong>
</font>
</center>

<% if @grants != [] && @grants != nil%>
<table border="1" style="width:100%">
<tr>
<td><strong><font size=5>Title</font></strong></td>
<td><strong><font size=5>Award Ceiling</font></strong></td>
<td><strong><font size=5>Description</font></strong></td>
<td><strong><font size=5>Additional Information</font></strong></td>
<td><strong><font size=5>Closing Date</font></strong></td>
</tr>

<% for item in @grants %>
<tr>
<td><%= item.title %></td>

<% if item.ceiling != '$0' && item.ceiling != nil && item.ceiling != '' && item.ceiling != '$1' && item.ceiling != '$2'%>
<td><%= item.ceiling %></td>
<% else %>
<td> See link for more information </td>
<% end %>


<% if item.description == "" %>
<td>See link for more information</td>

<%elsif item.description == nil%>
<td>See link for more information</td>

<% elsif item.description.sub('Description:', '').length > 720 %>
<td>
<%= truncate(item.description.sub('Description:', ''), length: 720) %>
<%= link_to 'Read more', '', class: "read-more-#{item.id}" %>
<script>
$('.read-more-<%= item.id %>').on('click', function(e) {
e.preventDefault()
$(this).parent().html('<%= escape_javascript item.description.sub('Description:', '') %>')
})
</script>
</td>
<%else%>
<td> <%=item.description.sub('Description:', '')%></td>
<%end%>


<td><center> <a href= <%= item.link %>>LINK</a><center></td>
<%unless item.date == nil%>
<td><% newdate = Date.parse item.date %>
<%= newdate.strftime("%D") %>
</td>
<%end%>
</tr>
<% end %>
<% else %>
<center>
<p> There are no Grants available to Entrepreneurs in this category at this time. However this list updates daily based on Grants.gov data, so feel free to check back later. </p>
</center>
<% end %>


</table>

</div>
</body>
</html>


I'm not sure where its happening but it seems to be rendering it about 25 times

Answer

You've accidentally encountered Rails collection rendering. You can read more about it here: https://robots.thoughtbot.com/rendering-collections-in-rails

When you do

<%= render @grants %>

Rails interprets this as you wanting to render the grants/_grant.html.erb (I think – or some similar path) partial once for each grant.

If you instead want to render it only once, try

<%= render "grants/grant" %>
Comments