5

我有一些模型需要自定义查找条件。例如,如果我有一个 Contact 模型,每次调用 Contact.find 时,我都想限制返回的联系人只属于正在使用的 Account。

我通过谷歌找到了这个(我已经定制了一点):

def self.find(*args)
  with_scope(:find => { :conditions =>  "account_id = #{$account.id}" }) do
    super(*args)
  end
end

这很好用,除了 account_id 不明确的少数情况,所以我将其调整为:

def self.find(*args)
  with_scope(:find => { :conditions =>  "#{self.to_s.downcase.pluralize}.account_id = #{$account.id}" }) do
    super(*args)
  end
end

这也很好用,但是,我希望它是干燥的。现在我有几个不同的模型,我希望使用这种功能。做这个的最好方式是什么?

当您回答时,请包含代码以帮助我们理解元编程 Ruby-fu。

(我使用的是 Rails v2.1)

4

3 回答 3

8

您没有告诉我们您正在使用哪个版本的 rails [编辑 - 它在 rails 2.1 上,因此遵循建议是完全可操作的],但我建议您使用以下表格而不是重载 find yourself :

account.contacts.find(...) 

这将自动将 find 包装在包含 user 子句的范围内(因为您有 account_id 我假设您的帐户在某个附近)

我建议您检查以下有关范围的资源

于 2008-09-17T06:05:55.047 回答
5

简的建议是合理的。假设您的模型如下所示:

class Contact < ActiveRecord::Base
  belongs_to :account
end

class Account < ActiveRecord::Base
  has_many :contacts
end

您应该使用contacts当前帐户的关联来确保您只获取Contact范围为该帐户的记录,如下所示:

@account.contacts

如果您想为您的联系人查询添加更多条件,您可以使用 find 指定它们:

@account.contacts.find(:conditions => { :activated => true })

如果您发现自己不断地查询激活的用户,您可以将其重构为一个命名范围:

class Contact < ActiveRecord::Base
  belongs_to :account
  named_scope :activated, :conditions => { :activated => true }
end

然后你会像这样使用它:

@account.contacts.activated
于 2008-09-17T13:13:27.953 回答
0

为了对您的问题给出具体答案,我建议将上述方法移入一个模块中,以包含在相关模型中;所以你会有

class Contact
  include NarrowFind
  ...
end

PS。注意 account_id 的 sql 转义,您可能应该使用该:conditions=>[".... =?", $account_id]语法。

于 2008-09-17T06:50:11.383 回答