开发者

Why is ruby returning array type instead of attribute

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开发者_JAVA技巧.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.where(:categorys_id => c.id).first

Item.where returns a scope, it doesn't actually construct or run the query.

Methods first and last will run the query with LIMIT and ORDER BY and will return the element.

Methods like each and all construct 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 of stuff in 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 IN operator. ruby @items = Item.where(:categorys_id => @categories.map(&:id)) #


I would rewrite your controller code as follows:

@categories = Category.find_all_by_user_id(session[:user_id], :include => :items)
@items      = @categories.map(&:items).flatten

Now in your view:

<% @items.each do |item| %>
  <tr>
    <td><%= item.name %></td>
  </tr>
<%end%>


Item.where(:categorys_id => c.id) will give you an ActiveRecord object, not an individual attributes. So when you iterate over these, i is an Item object, not an attribute.

Let's say you really wanted to output the item's name field, then you would do this:

<% @items.each do |i| %>
  <tr>
    <td><%= i.name %></td>
  </tr>
<%end%>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜