gpt4 book ai didi

ruby-on-rails - Ruby on Rails - ActiveRecord::Relation 计数方法错误?

转载 作者:数据小太阳 更新时间:2023-10-29 07:22:32 24 4
gpt4 key购买 nike

我正在编写一个应用程序,允许用户互相发送有关“优惠”的消息。

我想我可以节省一些工作并使用 Mailboxer gem 。

我正在遵循 RSpec 的测试驱动开发方法。我正在编写一个测试,以确保每个报价只允许一个 Conversation。报价属于两个不同的用户(提供报价的用户和收到报价的用户)。

这是我失败的测试:

describe "after a message is sent to the same user twice" do
before do
2.times { sending_user.message_user_regarding_offer! offer, receiving_user, random_string }
end
specify { sending_user.mailbox.conversations.count.should == 1 }
end

所以在测试运行之前,用户 sending_user 向 receiving_user 发送了两次消息。 message_user_regarding_offer! 看起来像这样:

def message_user_regarding_offer! offer, receiver, body
conversation = offer.conversation
if conversation.nil?
self.send_message(receiver, body, offer.conversation_subject)
else
self.reply_to_conversation(conversation, body)
# I put a binding.pry here to examine in console
end
offer.create_activity key: PublicActivityKeys.message_received, owner: self, recipient: receiver
end

在测试的第一次迭代中(发送第一条消息时)conversation 变量为 nil 因此发送消息并在两者之间创建对话用户。

在第二次迭代中,将返回在第一次迭代中创建的对话,并且用户回复该对话,但不会创建新对话。

一切正常,但测试失败,我不明白为什么!

当我在上面指定的位置的代码中放置一个 pry 绑定(bind)时,我可以检查发生了什么......现在给我谜语:

wtf ruby

self.mailbox.conversations[0] 返回一个 Conversation 实例

self.mailbox.conversations[1] 返回 nil

self.mailbox.conversations 清楚地显示了包含一个对象的集合。

self.mailbox.conversations.count 返回 2?!

那里发生了什么? count 方法不正确,我的测试失败了...

我错过了什么?或者这是一个错误?!

编辑

offer.conversation 看起来像这样:

  def conversation
Conversation.where({subject: conversation_subject}).last
end

offer.conversation_subject:

  def conversation_subject
"offer-#{self.id}"
end

编辑 2 - 在 pry 中显示第一次和第二次迭代

wtf ruby 2

还有...

Conversation.all.count 返回 1!

和:

Conversation.all == self.mailbox.conversations 返回 true

Conversation.all.count == self.mailbox.conversations.count 返回 false

如果数组相等怎么可能呢?我不知道这里发生了什么,现在已经花了几个小时了。认为这是一个错误?!

编辑 3

来自 Mailboxer gem 的来源......

def conversations(options = {})
conv = Conversation.participant(@messageable)

if options[:mailbox_type].present?
case options[:mailbox_type]
when 'inbox'
conv = Conversation.inbox(@messageable)
when 'sentbox'
conv = Conversation.sentbox(@messageable)
when 'trash'
conv = Conversation.trash(@messageable)
when 'not_trash'
conv = Conversation.not_trash(@messageable)
end
end

if (options.has_key?(:read) && options[:read]==false) || (options.has_key?(:unread) && options[:unread]==true)
conv = conv.unread(@messageable)
end

conv
end

reply_to_convesation 代码在这里可用 -> http://rubydoc.info/gems/mailboxer/frames .

只是看不出我做错了什么!可能会修改我的测试来解决这个问题。或者放弃 gem 并编写我自己的。

最佳答案

看这个Rails 3: Difference between Relation.count and Relation.all.count

简而言之,当您将计数应用于查询时,Rails 会忽略 select 列(如果有多个列)。这是因为

SQL's COUNT allows only one or less columns as parameters.

来自邮箱 code

 scope :participant, lambda {|participant|
select('DISTINCT conversations.*').
where('notifications.type'=> Message.name).
order("conversations.updated_at DESC").
joins(:receipts).merge(Receipt.recipient(participant))
}

self.mailbox.conversations.count 忽略 select('DISTINCT conversations.*') 并使用 计算 join 表>收据,本质上是计算其中包含重复对话收据的数量。

另一方面,self.mailbox.conversations.all.count 首先获取应用select 的记录,从而获取唯一的conversations然后数数。

self.mailbox.conversations.all == self.mailbox.conversations 因为它们都使用 select 查询数据库。

要解决您的问题,您可以使用 sending_user.mailbox.conversations.all.countsending_user.mailbox.conversations.group('conversations.id').length

关于ruby-on-rails - Ruby on Rails - ActiveRecord::Relation 计数方法错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18905700/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com