【问题标题】:Method works in development but not production Rails MongoDB方法适用于开发但不适用于生产 Rails MongoDB
【发布时间】:2016-04-17 14:10:03
【问题描述】:

我有一个优惠券课程,我希望我的应用程序检查优惠券上剩余的计数以及优惠券的日期是否已过期。我在课堂上有以下方法来检查这两个。

Coupon class

  def self.get(code)
   where(
    :code => (normalize_code(code)),
    :$and => [
      {
       :$or => [
         { :coupon_count.gte => 1  },
         { :coupon_count    => nil }
       ]
     }, {
       :$or => [
         { :expires_at.gt => Time.now.utc },
         { :expires_at    => nil      }
      ]
     }
    ]
  ).first
 end

当我输入优惠券时,这在开发中运行良好。但在生产中它不起作用。我使用我的 MongoDB shell 来创建优惠券,如下所示。

db.Coupon.insert({code:'#COUPONNAME',discount_percent: 10, expires_at: new ISODate("2016-05-18"), coupon_count: 10, "description": '1st cold visit sign-up'})

问题似乎出在优惠券检查 expires_at 日期时。在开发中它找到优惠券并工作,但在生产中它一直找不到优惠券。只是为了很好的衡量,这是我的控制器方法。

编辑 我认为问题出在日期上,但如果我删除日期查询,它仍然无法在生产中工作。我很困惑为什么这在生产中不起作用。它使用 MongoDB 3.0.10 和 mongoid 5.1.0 gem


charges_controller
  @code = params[:couponCode]

if !@code.blank?
  @coupon = Coupon.get(@code)

  if @coupon.nil?
    flash[:error] = 'Coupon code is not valid or expired.'
    redirect_to new_managers_charge_path(id: @reportapproval.id)
    return
  elsif @coupon.discount_percent == 100
    @reportapproval.report_paid = true
    @reportapproval.free_coupon_used = true
    @reportapproval.save!
    @coupon.coupon_count = @coupon.coupon_count - 1
    @coupon.save!
    redirect_to managers_dashboard_path, :notice => "You have successfully requested a pre-paid report from #{@reportapproval.tenant_last_name} with a 'No-Pay' intro coupon."
    return
  else
    @final_amount = @coupon.apply_discount(@amount.to_i)
    @discount_amount = (@amount.to_i - @final_amount.to_i)
  end

【问题讨论】:

  • 您的开发和生产环境有些不同,可能是数据(可能还有日期格式)或正在使用的驱动程序版本。在后一种情况下,它可能与查询参数的序列化有关。尝试将:code 条件移动到$and 条件“内”,并确保normalize_code(code) 的结果返回您所期望的。不太可能相关,但您可能真的是指 $exists 而不是 nil 值检查。记录发送到服务器的实际查询,并发现任何差异。
  • 集合不是db.coupons吗? codediscount_percent 字段如何更改? “退回优惠券”与您所做的 insert 不匹配。
  • 所以我从 Stripe 优惠券文档stripe.com/docs/recipes/coupons-for-charges 获得了这个过程,该方法通过代码找到优惠券。 discount_percent 不变。你是什​​么意思db.coupons,当我去MongoDB shell时,我可以使用db.Coupon.findOne()之类的东西来查找优惠券,但不能在我的rails应用程序中找到。你说的是这个吗?
  • @muistooshort 哇!所有这一切,我在 MongoDB shell 中调用了错误的模型。那是为了指出我的公然错误。你是最好的!将 create 方法更改为 db.coupons 并且效果很好。有趣的是,我在 rails irb 中使用了 Coupon,但不得不在 mongo shell 中进行更改
  • 请将您的评论标记为答案,我会给您信用

标签: ruby-on-rails mongodb mongoid


【解决方案1】:

如果你有一个Coupon Mongoid 模型,那么 MongoDB shell 中的集合就是db.coupons。这可以解释原因:

db.Coupon.insert(...)

在 MongoDB shell 中没有提供您期望在 Rails 代码中找到的内容。


就 Neil 关于 $exists 与显式 nil 检查的评论而言,我认为您确实需要 nil(在 MongoDB 中也称为 null)检查。在 MongoDB shell 中考虑这个:

> db.models.insert({ n: 11 })
> db.models.insert({ n: 0 })
> db.models.insert({ n: null })
> db.models.insert({ })
> db.models.find()
{ "_id" : ObjectId("571546e1ce2934dadf379479"), "n" : 11 }
{ "_id" : ObjectId("571546e4ce2934dadf37947a"), "n" : 0 }
{ "_id" : ObjectId("571546e7ce2934dadf37947b"), "n" : null }
{ "_id" : ObjectId("571546ecce2934dadf37947c") }

所以我们有一个集合,其中包含具有n、没有n、具有显式null 值的n 和非null 值的n

然后我们可以看到像:n => nil这样的Mongoid查询之间的区别:

> db.models.find({ n: null })
{ "_id" : ObjectId("571546e7ce2934dadf37947b"), "n" : null }
{ "_id" : ObjectId("571546ecce2934dadf37947c") }

:n.exists => true(又名:n => { :$exists => true }):

> db.models.find({ n: { $exists: true } })
{ "_id" : ObjectId("571546e1ce2934dadf379479"), "n" : 11 }
{ "_id" : ObjectId("571546e4ce2934dadf37947a"), "n" : 0 }
{ "_id" : ObjectId("571546e7ce2934dadf37947b"), "n" : null }

:n => { :$exists => false }:

> db.models.find({ n: { $exists: false } })
{ "_id" : ObjectId("571546ecce2934dadf37947c") }

所以:expires_at => nil 查询将找到没有expires_at 的文档以及expires_at 明确设置为nil 的文档。这两种情况都会发生在 Mongoid 上,除非你小心地调用 remove_attribute 而不是分配 nil 并且这两种情况都意味着“没有到期日”。

【讨论】:

    猜你喜欢
    • 2013-11-13
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 2013-11-26
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    相关资源
    最近更新 更多