Ruby on rails 查找用户是否已标记对象
我目前设置了一个实例,其中一个Ruby on rails 查找用户是否已标记对象,ruby-on-rails,associations,enumeration,Ruby On Rails,Associations,Enumeration,我目前设置了一个实例,其中一个Review有许多标志(通过多态性),一个用户有许多标志。到目前为止,一切正常,但我现在想做的是,在视图中,如果用户标记了某个特定的评论,则会显示一条消息,标记已提交,而不是标记该评论的链接 现在,我正在通过首先收集所有属于审查的标志,然后使用any?确定其中是否有当前用户的id。我想知道是否有一种更快/更有效的方法可以做到这一点?正是查找链让我变得全面,让它保持原样 注意:可标记的是一个局部变量,在本例中表示一个@review: <%= render "fl
Review
有许多标志(通过多态性),一个用户有许多标志。到目前为止,一切正常,但我现在想做的是,在视图中,如果用户标记了某个特定的评论,则会显示一条消息,标记已提交,而不是标记该评论的链接
现在,我正在通过首先收集所有属于审查的标志,然后使用any?
确定其中是否有当前用户的id。我想知道是否有一种更快/更有效的方法可以做到这一点?正是查找链让我变得全面,让它保持原样
注意:可标记的
是一个局部变量,在本例中表示一个@review
:
<%= render "flag", flaggable: @review %>
class Review
提交的旗帜
...
我认为这会奏效:
<% if user_signed_in? && flaggable.flags.exists?(owner: current_user) %>
- 在第1行,
@users
是一个ActiveRecord::Relationship,它尚未访问数据库。它目前只是将DB查询存储在内存中
- 在第2行,
@users
添加了一个条件,年龄应该是20
,因此查询现在变成类似于@users=users-who-are-admin-and-age-is-20
。这仍然是存储在内存中的查询。仍然没有数据库访问发生
- 在第3行,
。从@用户
调用每个
。通过调用此数组方法,@users
这是一个ActiveRecord::Relation
现在连接并查询数据库,然后数据库返回一个用户数组,现在可以像您在中所期望的那样循环。每个方法。(您会注意到,从3开始的行是视图文件中的代码)
- 在第6行,
.any?
从@users
调用。由于,@users
仍然是一个ActiveRecord::Relation
,但已经访问了数据库,并且数组已经在内存中(因为第3行),因此。any?
将不再访问数据库,其行为将类似于数组类的普通。any?
方法。然后您会意识到,如果数据库中有数百万条用户记录,那么@users
将占用大量内存,这不是很好。最好使用。查找部分存储在内存中的每个,其缺点是需要更多的DB调用
另一方面,注意使用.joins
而不是.includes
.joins
返回数组对象,而.includes
返回ActiveRecord::Relation。两者都有各自的用例。出于好奇,是什么让这比使用any更快/更好?
感谢您的详细解释。你的答案有一部分我不明白。当你说:但是,一旦你调用了任何数组方法,所有的flaggable.flags都将存储在内存中,这是在那时,只有在那时,检查匹配条件的循环才会发生。感谢你花时间解释这一点。你真的帮助我理解了两者的区别+1.
<div>
<% if user_signed_in? && flaggable.flags.any? { |r| r.user_id == current_user.id } %>
<p>Flag Submitted</p>
<% else %>
<%= link_to "Flag", [:new, flaggable, :flag], remote: true %>
<% end %>
...
</div>
<% if user_signed_in? && flaggable.flags.exists?(owner: current_user) %>
1 @users = User.where(is_admin: true)
2 @users = @users.where(age: 20)
3 <% @users.each do |user| %>
4 <%= user.name %>
5 <% end %>
6 <%= 'THERE IS A SANTA USER' if @users.any?{|user| user.name == 'Santa'} %>