为关联对象创建方法

时间:2012-01-19 10:17:10

标签: ruby-on-rails ruby activerecord

我有两种模式:

class User < ActiveRecord::Base
   has_many :accounts
end

class Account < ActiveRecord::Base
   belongs_to :user
end

我希望能够根据实例方法按某些条件对帐户进行排序。这是我想要用于此的方法:

def sorted
  partition { |account| account.is_referral?}.each do |a| 
    a.sort! {|a,b| a.label <=> b.label}
  end.flatten
end

其中is_referral?label都是Account类的实例方法。

所以我可以使用User.first.accounts.sorted来获取已排序的帐户。

如果我创建一个做某事的范围然后扩展它,我就能做到这一点:

scope :filtered, lambda { |filter|
    if filter == Listing::FILTER_INACTIVE
      where("status = ?", Account::STATUS_INACTIVE)
    elsif filter == Account::FILTER_ACTIVE
      where("status = ?", Account::STATUS_ACTIVE)      
    end
  } do
    def sorted
      partition { |account| account.is_referral?}.each do |a| 
        a.sort! {|a,b| a.label <=> b.label}
      end.flatten
    end
  end

现在我可以使用User.accounts.filtered(Account::FILTER_ACTIVE).sorted。我认为这是因为scope.class返回ActiveRecord::RelationUser.first.accounts.class返回Array

我也试过这个:

scope :sorted, lambda { |object|
  object.partition { |account| account.is_referral?}.each do |a| 
    a.sort! {|a,b| a.label <=> b.label}
  end.flatten
}

但这会为NoMethodError抛出nil.partition

感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

您可以通过执行

来定义关联的代理方法
class User < ActiveRecord::Base
  has_many :accounts do
    def sorted
      proxy_target.partition { |account| account.is_referral?}.each do |a| 
           a.sort! {|a,b| a.label <=> b.label}
      end.flatten
    end
  end
end

请参阅http://guides.rubyonrails.org/association_basics.html#association-extensions

User.last.accounts(true).sorted一起使用以获取结果,否则您的关联将不会被加载,因此您将收到空数组。