создание метода для связанных объектов - PullRequest
0 голосов
/ 19 января 2012

У меня есть две модели:

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::Relation и User.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 Ответ

1 голос
/ 19 января 2012

Вы можете определить прокси-методы для ассоциаций, выполнив

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, чтобы получить результаты, потому что в противном случае ваша ассоциация не будет загружена, и вы получите пустой массив в результате.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...