为什么 ruby 返回数组类型而不是属性
我的视图中有这段代码
<% @items.each do |i| %>
<tr>
<td><%= i.name %></td>
</tr>
<%end%>
,控制器中有这段代码
@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
,当我运行它时,该代码会生成一个如下所示的页面: “您的用户名是一个物品物品” 而不是 “您的用户名是数字堡垒海洋十一定居者”
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"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您想要实现的目标可以这样完成:
Item.where
返回一个范围,它实际上并不构造或运行查询。方法
first
和last
将使用LIMIT
和ORDER BY
运行查询,并返回元素。each
和all
等方法构造并运行查询并返回结果数组。代码审查
您的控制器代码容易受到 SQL 注入,如果
session[:user_id]
中存在恶意内容,请想象一下。"#{stuff}"
在 Ruby 中不会对stuff
进行任何转义。要摆脱注入问题:
ruby
@categories = Category.where(:users_id => session[:user_id]) # 您确定该列不是 user_id 而是 users_id 吗?
我们应该做的第二件事是避免进行 N + 1 查询,其中 N 是结果类别的数量。
一个好的方法是使用 SQL
IN
运算符。红宝石
@items = Item.where(:categorys_id => @categories.map(&:id)) #
What you are trying to achieve can be done like this:
Item.where
returns a scope, it doesn't actually construct or run the query.Methods
first
andlast
will run the query withLIMIT
andORDER BY
and will return the element.Methods like
each
andall
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 ofstuff
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:
Now in your view:
Item.where(:categorys_id => c.id)
将为您提供一个 ActiveRecord 对象,而不是单个属性。因此,当您迭代这些时,i
是一个Item
对象,而不是属性。假设您确实想输出项目的
name
字段,那么您可以这样做:Item.where(:categorys_id => c.id)
will give you an ActiveRecord object, not an individual attributes. So when you iterate over these,i
is anItem
object, not an attribute.Let's say you really wanted to output the item's
name
field, then you would do this: