admin管理员组文章数量:1399127
I'm trying to refactor a scope within a Concern so that the scope gets most of its logic by calling different class methods, depending on an arg.
With "public" class methods, that works fine.
But I want those class methods to be private, so they are not mistaken for scopes and called by other developers. (because this will lead to unexpected results in the app.)
I tried a suggestion here and every other way I could find to declare these class methods private, but when I do that, they are inaccessible from within the scope.
module OrderingScopes
extend ActiveSupport::Concern
included do
# This scope can handle methods like :method and :reverse_method
scope :order_by, lambda { |method|
method = method.dup.to_s
reverse = method.sub!(/^reverse_/, "")
scope = :"order_by_#{method}";
# This check fails
return all unless private_methods(false).include?(scope)
scope = send(scope)
scope = scope.reverse_order if reverse
# Disambiguate grouped result order by adding an order by :id
scope = scope.order(arel_table[:id].desc)
scope
}
private_class_method :order_by_method_name
end
class_methods do
def order_by_method_name
end
end
end
Also tried:
class_methods do
private
def order_by_method_name
end
end
In both cases the scope fails:
> Model.order_by(:method_name)
included do
scope :order_by, lambda { |method|
method = method.dup.to_s
reverse = method.sub!(/^reverse_/, "")
scope = :"order_by_#{method}";
debugger
> private_methods(false).include?(:order_by_method_name)
false
> respond_to?(:order_by_method_name)
false
Is there a way to do this?
I'm trying to refactor a scope within a Concern so that the scope gets most of its logic by calling different class methods, depending on an arg.
With "public" class methods, that works fine.
But I want those class methods to be private, so they are not mistaken for scopes and called by other developers. (because this will lead to unexpected results in the app.)
I tried a suggestion here and every other way I could find to declare these class methods private, but when I do that, they are inaccessible from within the scope.
module OrderingScopes
extend ActiveSupport::Concern
included do
# This scope can handle methods like :method and :reverse_method
scope :order_by, lambda { |method|
method = method.dup.to_s
reverse = method.sub!(/^reverse_/, "")
scope = :"order_by_#{method}";
# This check fails
return all unless private_methods(false).include?(scope)
scope = send(scope)
scope = scope.reverse_order if reverse
# Disambiguate grouped result order by adding an order by :id
scope = scope.order(arel_table[:id].desc)
scope
}
private_class_method :order_by_method_name
end
class_methods do
def order_by_method_name
end
end
end
Also tried:
class_methods do
private
def order_by_method_name
end
end
In both cases the scope fails:
> Model.order_by(:method_name)
included do
scope :order_by, lambda { |method|
method = method.dup.to_s
reverse = method.sub!(/^reverse_/, "")
scope = :"order_by_#{method}";
debugger
> private_methods(false).include?(:order_by_method_name)
false
> respond_to?(:order_by_method_name)
false
Is there a way to do this?
Share Improve this question edited Mar 25 at 16:47 nimmolo asked Mar 25 at 7:26 nimmolonimmolo 5856 silver badges26 bronze badges1 Answer
Reset to default 2Rails automatically defines scope methods on a relation object and delegates to your model's class method, but only if method is public.
You can work around this by copying how rails defines the delegate method:
scope :order_by, lambda { |method|
scoping { model.send(:"order_by_#{method}") }
}
https://api.rubyonrails./classes/ActiveRecord/Relation.html#method-i-scoping
Note, that within a scope
you're working with an ActiveRecord::Relation
object. You can use model
attribute reader to get your model class. Since private class methods are not copied into the relation class you have to run your check on the model itself:
# private_methods(false).include?(scope)
model.private_methods(false).include?(scope)
本文标签: activerecordRails ActiveSupportConcernscope can39t call private class methodStack Overflow
版权声明:本文标题:activerecord - Rails ActiveSupport::Concern — scope can't call private class method - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744212912a2595504.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论