在我的Rails 4应用程序中,我有一个Item模型和一个Flag模型。项目has_many
标志。标志belong_to
项目。标记具有item_id
,user_id
和reason
属性。我正在使用enum
作为待处理状态。我需要最有效的方法来获取flags表中不存在的项,因为我有一个非常大的表。我还需要确保当用户点击生成另一个随机项时,它不会重复当前的随机项。之后可以随时重复,只是不要背靠背。
这是我到目前为止所做的:
def pending_item
@pending_items = Item.joins("LEFT OUTER JOIN flags ON flags.item_id = items.id").
where("items.user_id != #{current_user.id} and flags.id is null")
@pending_item = @pending_badges.offset(rand @pending_badges.count).first
end
有比这更有效的方式吗?
我怎样才能确保同一pending_item
没有背靠背重复?
答案 0 :(得分:1)
你所拥有的是在我所知道的数据库中最快的方式(这就是为什么我给它here)。许多其他Stack Overflow帖子讨论了从表中有效选择随机行的方法;如果您从整个表格中进行选择,则可以使用更有效的方法,但是当您从查询中选择随机结果时,这些方法不适用。
如果性能至关重要,那么在内存中执行它会快得多。
.sample
或其他随机成员。这需要付出很多努力,所以你真的不得不这样做。
关于避免重复,可靠地执行此操作的唯一方法是存储显示的最后一个待处理项目并将其从查询中排除
def pending_item
@pending_items = UserItem.
joins("LEFT OUTER JOIN flags ON flags.item_id = items.id").
where("items.user_id != ?", current_user.id).
where("flags.id is null").
where("items.id != ?", previous_shown_item_id)
@pending_item = @pending_badges.offset(rand @pending_badges.count).first
end
或者,如果您在内存中进行随机选择,请在执行此操作时排除最后显示的待处理项目。