- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Rails 4.2.5
, Mongoid 5.1.0
我有三个模型 - Mailbox
, Communication
,和Message
.
mailbox.rb
class Mailbox
include Mongoid::Document
belongs_to :user
has_many :communications
end
communication.rb
class Communication
include Mongoid::Document
include Mongoid::Timestamps
include AASM
belongs_to :mailbox
has_and_belongs_to_many :messages, autosave: true
field :read_at, type: DateTime
field :box, type: String
field :touched_at, type: DateTime
field :import_thread_id, type: Integer
scope :inbox, -> { where(:box => 'inbox') }
end
message.rb
class Message
include Mongoid::Document
include Mongoid::Timestamps
attr_accessor :communication_id
has_and_belongs_to_many :communications, autosave: true
belongs_to :from_user, class_name: 'User'
belongs_to :to_user, class_name: 'User'
field :subject, type: String
field :body, type: String
field :sent_at, type: DateTime
end
我正在使用身份验证 gem devise
,它可以访问 current_user
helper,它指向当前登录的用户。
我已经为满足以下条件的 Controller 构建了一个查询:获取current_user
的mailbox
,其communication
的过滤条件为 box
场,其中 box == 'inbox'
。它的构造如下(并且正在运行):
current_user.mailbox.communications.where(:box => 'inbox')
当我尝试基于此查询进行构建时,出现了问题。我希望链接查询,以便我只获得 messages
谁的last
消息不是来自current_user
。我知道 .last 方法,它返回最新的记录。我提出了以下查询,但无法理解需要调整哪些内容才能使其工作:
current_user.mailbox.communications.where(:box => 'inbox').where(:messages.last.from_user => {'$ne' => current_user})
该查询产生以下结果: undefined method 'from_user' for #<Origin::Key:0x007fd2295ff6d8>
我目前能够通过执行以下操作来完成此任务,我知道这样做效率非常低,并且希望立即更改:
mb = current_user.mailbox.communications.inbox
comms = mb.reject {|c| c.messages.last.from_user == current_user}
我希望将此逻辑从 ruby 移至实际的数据库查询。预先感谢任何在这方面为我提供帮助的人,如果有更多信息对我有帮助,请告诉我。
最佳答案
好吧,这里发生的事情有点困惑,并且与 Mongoid 在进行关联时实际上能够有多聪明有关。
特别是在两个关联之间“交叉”时如何构造查询。
对于您的第一个查询:
current_user.mailbox.communications.where(:box => 'inbox')
这对于 mongoid 来说很酷,因为它实际上只是脱糖为真正的 2 个数据库调用:
现在,当我们处理您的下一个查询时,
current_user.mailbox.communications.where(:box => 'inbox').where(:messages.last.from_user => {'$ne' => current_user})
是 Mongoid 开始感到困惑的时候。
这是主要问题:当您使用“where”时,您正在查询您所在的集合。您不会交叉关联。
where(:messages.last.from_user => {'$ne' => current_user}) 实际上所做的是不检查消息关联。 Mongoid 实际上做的是在通信文档中搜索具有类似于以下 JSON 路径的属性:communication['messages']['last']['from_user']。
现在您知道原因了,您可以得到您想要的东西,但是这需要比同等的 ActiveRecord 工作付出更多的努力。
以下是您获得所需内容的更多方法:
user_id = current_user.id
communication_ids = current_user.mailbox.communications.where(:box => 'inbox').pluck(:_id)
# We're going to need to work around the fact there is no 'group by' in
# Mongoid, so there's really no way to get the 'last' entry in a set
messages_for_communications = Messages.where(:communications_ids => {"$in" => communications_ids}).pluck(
[:_id, :communications_ids, :from_user_id, :sent_at]
)
# Now that we've got a hash, we need to expand it per-communication,
# And we will throw out communications that don't involve the user
messages_with_communication_ids = messages_for_communications.flat_map do |mesg|
message_set = []
mesg["communications_ids"].each do |c_id|
if communication_ids.include?(c_id)
message_set << ({:id => mesg["_id"],
:communication_id => c_id,
:from_user => mesg["from_user_id"],
:sent_at => mesg["sent_at"]})
end
message_set
end
# Group by communication_id
grouped_messages = messages_with_communication_ids.group_by { |msg| mesg[:communication_id] }
communications_and_message_ids = {}
grouped_messages.each_pair do |k,v|
sorted_messages = v.sort_by { |msg| msg[:sent_at] }
if sorted_messages.last[:from_user] != user_id
communications_and_message_ids[k] = sorted_messages.last[:id]
end
end
# This is now a hash of {:communication_id => :last_message_id}
communications_and_message_ids
我不确定我的代码是否 100%(您可能需要检查文档中的字段名称以确保我正在搜索正确的字段名称),但我认为您已经了解了一般模式。
关于ruby-on-rails - MongoDB 对 HABTM 关系(Mongoid、RoR)进行条件聚合查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35466893/
假设我正在构建一个拥有许多博客和用户的引擎。用户可以拥有多个博客,博客也可以拥有多个用户(用户 hasAndBelongsToMany blogs)。我将创建一个名为 users_blogs 的数据透
我正在尝试使用以下结构保存数据: 如您所见,用户和体验表之间存在 HABTM 关联。另一个 HABTM 位于 experiences_users 和 tags 之间。我创建了以下表单: create(
我有两张 table ,questions和 tags ,具有 HABTM 关系。添加问题时,我希望能够为问题指定一个标签(这只是第一个标签,以后可以添加更多标签)。标签是从他们的 table 上拉出
我有一个 HABTM 关联,但无法将数据保存到连接表中。 这是我的 Controller : public function create($id) { if (!i
之前问过,但仍然蒙在鼓里。 cakePHP HABTM, am I getting it all wrong? 会再试一次: 我有两个表:stores 和 managers 我想创建一个新表,mana
您好,我有一个用 cakephp 开发的网站。我有两张 table :成分属性 表之间的关系是 HasAndBelongsToMany(HABTM)。这是我的模型: class Ingredient
我正在尝试保存订单和订单中的产品。 正在保存订单,但没有保存产品。 我有一个 orders 表和一个 products 表以及一个 orders_products 表。 在订单模型中,我设置了 $ha
我目前有以下 SQL 数据库: CREATE TABLE `users` ( `id` INT(10) NOT NULL AUTO_INCREMENT, `name` VARCHAR(40),
我正在尝试保存订单和订单中的产品。 正在保存订单,但没有保存产品。 我有一个 orders 表和一个 products 表以及一个 orders_products 表。 在订单模型中,我设置了 $ha
我在用户和位置之间建立了 HABTM 关系。两种型号都有相应的 $hasAndBelongsToMany变量集。 当我管理用户位置时,我想删除用户和位置之间的关联,而不是位置。显然这个位置可能属于其他
序言:几天前我请 question 解决 HABTM 过滤器,即使有教程我也无法做到,所以“Obi Kwan Kenobi 你是我唯一的希望”。 我想要实现的目标:通过在 StaffStaffgrou
我正在自学 Rails,作为一个测试项目,我正在模拟一个类似于 stackoverflow 的简单问答应用程序。 在我的简化版本中,我有: 问题 答案 用户(问题和答案的作者) 我知道答案属于问题。
我正在尝试连接我拥有的两个连接表的值并根据条件关系显示结果...但我遇到了一些问题 我有一个用户模型(:name, :password, :email),事件模型(:name, :etc) 和兴趣模型
rails 3.2.3, ruby 1.9.3p194 尝试用 HABTM 相关子项目保存一个项目,我覆盖默认生成的 SQL,调用母项目和每个相关子项目的名称属性。如何正确指定关联的子项目名称? #{
到目前为止,我当前的 HABTM 实现与 :has_and_belongs_to_many 一起工作。 Notification 和 Privacy 都继承自 Preference。偏好是 STI。我
我有两个具有HABTM关系的模型-用户和角色。 用户-has_and_belongs_to_many:roles 角色-属于:user 我想在联接(users_roles表)中添加一个唯一性约束,该约
是否可以在 Rails 3 中的 habtm 关系上使用计数器缓存? 我真的需要它来加快我的申请速度。 最佳答案 HABTM 没有内置方法,但创建自己的计数器缓存很简单(实际上,在发明 counter
我有一个用户表和一个报告表,通过 HABTM 关系连接。 我可以保存在 reports_users 表中创建正确记录的报告,我可以使用 $this->User->ReportsUser->.. 查看关
我有两个非常简单的类: class Contact include Mongoid::Document has_and_belongs_to_many :organizations,
我有两个模型,帖子和标签。发布 HasAndBelongsToMany 标签。 假设 Post 1 具有标签 world、news 和 paper。 现在在连接表中,我想删除标签“paper”和Pos
我是一名优秀的程序员,十分优秀!