gpt4 book ai didi

ruby-on-rails-3 - 使用 except 的范围不起作用 Rails

转载 作者:行者123 更新时间:2023-12-01 01:16:09 27 4
gpt4 key购买 nike

我写了嗨,但SO不会让它,所以我写更长的句子:)顺便说一句嗨。

看起来我的范围不起作用。

我写了那个范围:
scope :ordered, ->(field, order) { except(:order).order("#{field} #{order}") }
但它在检查 SQL 时返回以下内容:

irb >p.levels.ordered("name", "ASC").to_sql
=> "SELECT \"levels\".* FROM \"levels\" WHERE (\"levels\".pie_id = 6 AND (\"levels\".\"parent_id\" = 0)) ORDER BY position ASC, name ASC"

注意: position ASC不应该在那里

但是在我的范围之前添加时它可以工作......
irb > p.levels.except(:order).ordered("name", "ASC").to_sql
=> "SELECT \"levels\".* FROM \"levels\" WHERE (\"levels\".pie_id = 6 AND (\"levels\".\"parent_id\" = 0)) ORDER BY name ASC" `

除了在范围内可用吗?或者你有什么可以帮助我的吗?

ruby 1.9.2p290

导轨 3.0.14

谢谢

最佳答案

您可能已经想到可以通过使用 reorder 来实现您的目标。 .所以这是我的理论,为什么 reorder作品和except没有。

重要的是,像 order 这样的方法, where , exceptActiveRecord::Relation 的实例处理,而范围,例如ordered在您的示例中,由 ActiveRecord::Relation 的实例委托(delegate)到你的模型课。
some_relation.order(:x)方法只返回 some_relation 的新副本与 :x添加到其列表 order_values .同样,some_relation.except(:order)将返回 some_relation 的副本有空 order_values .只要调用链由此类关系方法组成,except像我们预期的那样工作。

对作用域方法的调用,当作用域实现为 lambda 返回关系时,会以 scoped 返回的模型关系合并结束。与 lambda 返回的关系:

scopes[name] = lambda do |*args|
options = scope_options.is_a?(Proc) ? scope_options.call(*args) : scope_options

relation = if options.is_a?(Hash)
scoped.apply_finder_options(options)
elsif options
scoped.merge(options) # <- here options is what returned by your :ordered lambda
else
scoped
end

extension ? relation.extending(extension) : relation
end

还有这个 merge不保留 except 的效果如果仅对要合并的关系之一进行。如果我们合并 ab , 和 b没有设置订单,但是 a确实,结果仍然有顺序。现在 reorder用一个技巧来解决它:它设置特殊标志 reorder_flag关于控制方式的关系 merge携带 order_values .

这是我的测试样本。我正在使用 default_scope将订单注入(inject) Product#scoped .在您的示例中,订单可能被注入(inject) Level#scoped通过 Pie 中的关联,看起来像 has_many :levels, :order => 'position' .
class Product < ActiveRecord::Base
default_scope order('id DESC')
scope :random_order, lambda {
r = order('random()')
puts "from lambda: " + r.order_values.inspect
r
}
end

# in console:

>> Product.scoped.order_values
=> ["id DESC"]

>> Product.random_order.order_values
from lambda: ["id DESC", "random()"]
=> ["id DESC", "id DESC", "random()"]

# now if I change the first line of lambda to
# r = except(:order).order('random()')

>> Product.random_order.order_values
from lambda: ["random()"]
=> ["id DESC", "random()"]

如您所见,因为 Product.scopedid DESC顺序,尽管它已从范围返回的关系中清除,但它仍出现在结果中。

以下是相关来源的链接列表:
  • relation's order and reorder methods
  • relation's except method
  • relation's merge method , 注意如何 reorder_flag用于第 29 行
  • scope method
  • 关于ruby-on-rails-3 - 使用 except 的范围不起作用 Rails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12009736/

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