链接此查询会引发错误
Chaining this query throws error
我正在尝试查询:
- Finds/Gets 对象 (Coupon.code)
- 检查优惠券是否过期 (expires_at)
- 检查优惠券是否已用完。 (coupons_remaining)
我使用较新版本的 ruby 获得了一些语法,但它不适用于我的 2.2.1 版本我的语法是
def self.get(code)
where(code: normalize_code(code)).
where("coupon_count > ? OR coupon_count IS NULL", 0).
where("expires_at > ? OR expires_at IS NULL", Time.now).
take(1)
end
这会引发 wrong number of arguments (2 for 1)
错误,这是因为我的 rails 似乎无法识别 2 个参数 ("coupon_count > ? OR coupon_count IS NULL", 0) 所以我尝试更改它但是当我把它们改成这样的时候(我心里觉得很不对劲)
def self.get(code)
where(code: normalize_code(code)).
where(coupon_count: self.coupon_count > 0 || self.coupon_count.nil? ).
where(expires_at: self.expires_at > Time.now || self.expires_at.nil? ).
take(1)
end
我得到undefined method `coupon_count' for Coupon:Class
我缺乏想法有人可以帮助我在我的模型中获得此 get 方法的语法吗?顺便说一句,如果重要的话,我正在使用 mongoid 5.1.0
您定义了一个 class 方法,因此 self
在这种情况下引用 Coupon
class 而不是 Coupon
实例。
尝试以下操作:
scope :not_expired, -> { where("expires_at > ? OR expires_at IS NULL", Time.now) }
scope :previously_used, -> { where("coupon_count > 0 OR coupon_count IS NULL") }
def self.get(code)
previously_used.not_expired.find_by!(code: normalize_code(code))
end
我感受到你的痛苦。在 MongoDB 中组合 OR 和 AND 有点混乱,因为您根本没有真正使用查询语言,您只是在构建哈希。如果您可能将多个条件应用于同一字段,则类似的复杂情况也适用。这也是为什么您不能像使用 ActiveRecord 那样包含 SQL-like 片段的原因。
例如表示:
"coupon_count > ? OR coupon_count IS NULL", 0
你需要像这样构建一个哈希:
:$or => [
{ :coupon_count.gt => 0 },
{ :coupon_count => nil }
]
但如果您尝试向其添加另一个 OR,您将覆盖现有的 :$or
键并导致混淆。相反,您需要注意会有多个 OR,并通过说 :$and
:
手动避免重复
:$and => [
{
:$or => [
{ :coupon_count.gt => 0 },
{ :coupon_count => nil }
]
}, {
:$or => [
{ :expires_at.gt => Time.now },
{ :expires_at => nil }
]
}
]
然后添加 code
条件就很简单了:
:code => normalize_code(code),
:$and => [ ... ]
这使得整个事情变得相当可怕的怪物:
def self.get(code)
where(
:code => normalize_code(code),
:$and => [
{
:$or => [
{ :coupon_count.gt => 0 },
{ :coupon_count => nil }
]
}, {
:$or => [
{ :expires_at.gt => Time.now },
{ :expires_at => nil }
]
}
]
).first
end
您也可以使用 find_by(that_big_mess)
而不是 where(that_big_mess).first
。此外,如果您希望查询匹配多个文档,那么您可能想要添加一个 order
调用以确保您获得所需的那个。您可能会使用 and
和 or
查询方法而不是单个哈希,但我怀疑它会使事情易于阅读、理解或维护。
我尽量避免使用 MongoDB 的 OR,因为查询会很快失去理智,你会留下一些你不想考虑太多的令人毛骨悚然的恐惧。您通常最好使用生成的字段预先计算部分查询(您必须维护和完整性检查以确保它们是正确的);例如,您可以添加另一个字段,如果 coupon_count
为正或 nil
则为真,然后在 coupon_count
更改时在 before_validation
挂钩中更新该字段。
我正在尝试查询:
- Finds/Gets 对象 (Coupon.code)
- 检查优惠券是否过期 (expires_at)
- 检查优惠券是否已用完。 (coupons_remaining)
我使用较新版本的 ruby 获得了一些语法,但它不适用于我的 2.2.1 版本我的语法是
def self.get(code)
where(code: normalize_code(code)).
where("coupon_count > ? OR coupon_count IS NULL", 0).
where("expires_at > ? OR expires_at IS NULL", Time.now).
take(1)
end
这会引发 wrong number of arguments (2 for 1)
错误,这是因为我的 rails 似乎无法识别 2 个参数 ("coupon_count > ? OR coupon_count IS NULL", 0) 所以我尝试更改它但是当我把它们改成这样的时候(我心里觉得很不对劲)
def self.get(code)
where(code: normalize_code(code)).
where(coupon_count: self.coupon_count > 0 || self.coupon_count.nil? ).
where(expires_at: self.expires_at > Time.now || self.expires_at.nil? ).
take(1)
end
我得到undefined method `coupon_count' for Coupon:Class
我缺乏想法有人可以帮助我在我的模型中获得此 get 方法的语法吗?顺便说一句,如果重要的话,我正在使用 mongoid 5.1.0
您定义了一个 class 方法,因此 self
在这种情况下引用 Coupon
class 而不是 Coupon
实例。
尝试以下操作:
scope :not_expired, -> { where("expires_at > ? OR expires_at IS NULL", Time.now) }
scope :previously_used, -> { where("coupon_count > 0 OR coupon_count IS NULL") }
def self.get(code)
previously_used.not_expired.find_by!(code: normalize_code(code))
end
我感受到你的痛苦。在 MongoDB 中组合 OR 和 AND 有点混乱,因为您根本没有真正使用查询语言,您只是在构建哈希。如果您可能将多个条件应用于同一字段,则类似的复杂情况也适用。这也是为什么您不能像使用 ActiveRecord 那样包含 SQL-like 片段的原因。
例如表示:
"coupon_count > ? OR coupon_count IS NULL", 0
你需要像这样构建一个哈希:
:$or => [
{ :coupon_count.gt => 0 },
{ :coupon_count => nil }
]
但如果您尝试向其添加另一个 OR,您将覆盖现有的 :$or
键并导致混淆。相反,您需要注意会有多个 OR,并通过说 :$and
:
:$and => [
{
:$or => [
{ :coupon_count.gt => 0 },
{ :coupon_count => nil }
]
}, {
:$or => [
{ :expires_at.gt => Time.now },
{ :expires_at => nil }
]
}
]
然后添加 code
条件就很简单了:
:code => normalize_code(code),
:$and => [ ... ]
这使得整个事情变得相当可怕的怪物:
def self.get(code)
where(
:code => normalize_code(code),
:$and => [
{
:$or => [
{ :coupon_count.gt => 0 },
{ :coupon_count => nil }
]
}, {
:$or => [
{ :expires_at.gt => Time.now },
{ :expires_at => nil }
]
}
]
).first
end
您也可以使用 find_by(that_big_mess)
而不是 where(that_big_mess).first
。此外,如果您希望查询匹配多个文档,那么您可能想要添加一个 order
调用以确保您获得所需的那个。您可能会使用 and
和 or
查询方法而不是单个哈希,但我怀疑它会使事情易于阅读、理解或维护。
我尽量避免使用 MongoDB 的 OR,因为查询会很快失去理智,你会留下一些你不想考虑太多的令人毛骨悚然的恐惧。您通常最好使用生成的字段预先计算部分查询(您必须维护和完整性检查以确保它们是正确的);例如,您可以添加另一个字段,如果 coupon_count
为正或 nil
则为真,然后在 coupon_count
更改时在 before_validation
挂钩中更新该字段。