I have this code in my view
<% @items.each do |i| %>
<tr>
<td><%= i.name %></td>
</tr>
<%end%>
and this code in my controller
@categories = Category.find_by_sql("SELECT * FROM categories WHERE users_id =#{session[:user_id]}")
@categories.each do |c|
@items << (Item.where(:categorys_id => c.id))
end
and when I run it, the code generates a page looking like this:
“Your username is a Item Item Item”
instead of
“Your username is a Digital Fortress Oceans Eleven Settlers”
What you are trying to achieve can be done like this:
Item.wherereturns a scope, it doesn’t actually construct or run the query.Methods
firstandlastwill run the query withLIMITandORDER BYand will return the element.Methods like
eachandallconstruct and run the query and return the array of results.Code review
Your controller code is prone to SQL injection, image if something evil was in
session[:user_id]."#{stuff}"does not do any escaping ofstuffin Ruby.To get rid of the injection problem:
ruby
@categories = Category.where(:users_id => session[:user_id]) # Are you sure the column is not user_id but users_id?
The second thing we should do is to avoid doing N + 1 query where N is the number of resulting categories.
An OK way to do this is by using the SQL
INoperator.ruby
@items = Item.where(:categorys_id => @categories.map(&:id)) #