gpt4 book ai didi

ruby-on-rails - 在命名范围之间共享方法

转载 作者:行者123 更新时间:2023-12-03 15:56:55 25 4
gpt4 key购买 nike

我有一堆命名范围,其中一个有一个方法,我想在其他命名范围之间共享。我已经通过使用 define_method 和一个 lambda 来实现这一点。但是,仍然有一些重复的代码,我想知道有没有更好的方法?

这是我所拥有的一个简化示例。假设我有一个项目表,每个项目都有很多用户。

在用户模型中,我有...

filter_by_name = lambda { |name| detect {|user| user.name == name} }

named_scope :active, :conditions => {:active => true} do
define_method :filter_by_name, filter_by_name
end

named_scope :inactive, :conditions => {:active => false} do
define_method :filter_by_name, filter_by_name
end

named_scope :have_logged_in, :conditions => {:logged_in => true} do
define_method :filter_by_name, filter_by_name
end

然后我会像...
active_users = Project.find(1).users.active

some_users = active_users.filter_by_name ["Pete", "Alan"]
other_users = active_users.filter_by_name "Rob"

logged_in_users = Project.find(1).users.logged_in

more_users = logged_in_users.filter_by_name "John"

最佳答案

命名的作用域可以被链接起来,所以你让自己变得比你需要的更难。

在用户模型中定义以下内容时将得到您想要的:

class User < ActiveRecord::Base
...
named_scope :filter_by_name, lambda { |name|
{:conditions => { :name => name} }
}

named_scope :active, :conditions => {:active => true}

named_scope :inactive, :conditions => {:active => false}

named_scope :have_logged_in, :conditions => {:logged_in => true}
end

然后以下代码段将起作用:
active_users = Project.find(1).users.active

some_users = active_users.filter_by_name( ["Pete", "Alan"]
other_users = active_users.filter_by_name "Rob"

logged_in_users = Project.find(1).users.have_logged_in

more_users = logged_in_users.filter_by_name "John"

我看到您正在使用 detect ,可能是为了避免对数据库的过多点击。但是你的例子没有正确使用它。 Detect 仅返回列表中块为其返回 true 的第一个元素。在上面的例子中, some_users将只是一个记录,第一个名为“Pete”或“Alan”的用户。如果您希望获得所有名为“Pete”或“Alan”的用户,那么您需要 select .如果你想要 select那么最好使用命名范围。

命名范围在评估时返回一个特殊对象,该对象包含构建 SQL 语句以生成结果所需的组件,链接其他命名范围仍然不执行该语句。直到您尝试访问结果集上的方法,例如调用 each 或 map。

关于ruby-on-rails - 在命名范围之间共享方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2380842/

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