shime
shime

Reputation: 9018

creating a method for associated objects

I have two models:

class User < ActiveRecord::Base
   has_many :accounts
end

class Account < ActiveRecord::Base
   belongs_to :user
end

I want to be able to sort my accounts by some criteria based on an instance method. This is a method I want to use for this:

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

where is_referral? and label are both instance methods of Account class.

So I could get sorted accounts with User.first.accounts.sorted.

I am able to do this if I create a scope that does something and then extend it:

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

Now I can use User.accounts.filtered(Account::FILTER_ACTIVE).sorted. I figure this is because scope.class returns ActiveRecord::Relation and User.first.accounts.class returns Array.

I've also tried this one:

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

But this throws NoMethodError for nil.partition.

Any help is appreciated.

Upvotes: 0

Views: 120

Answers (1)

axsuul
axsuul

Reputation: 7490

You can define proxy methods on associations by doing

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

See http://guides.rubyonrails.org/association_basics.html#association-extensions

Use this with User.last.accounts(true).sorted to get the results, because otherwise your association will not be loaded and you will receive empty array as a result.

Upvotes: 1

Related Questions