Kylo
Kylo

Reputation: 2320

ActiveRecord and loading data from related tables

My model looks like this (example):

class Bank < ActiveRecord::Base
  has_and_belongs_to_many :currencies
  # other stuff
end

When I want to get some bank from database i do:

bank = Bank.first :joins => :some_table,
         :conditions => {
           #some conditions
         }

Now, is there any way to explicitly retrieve currencies from database for provided conditions and sort them in some order and store them in bank.currencies ?

I'm doing something like this:

bank.currencies.reject! { |c| c.value < something }
bank.currencies.sort! { |x,y| x.value <=> y.value }

It works but this way I retrieve all records and filter them by myself. I would like to have DBMS do it for me.

This is just an example with banks and currencies. I have some big records and I think it is important just to retrieve those which interest me.

Upvotes: 0

Views: 302

Answers (2)

NeilS
NeilS

Reputation: 602

You can issue "find" clauses on the relationship, like this:

bank.currencies.find(:all, :conditions => {something}, :order => {something})

or, if you prefer:

bank.currencies.all(:conditions => {something}, :order => {something})

All the standard ActiveRecord options should be available - e.g. limit, order etc.

Of course, if you find yourself re-using the query logic, you can declare named scopes on the Currency model - say, 'with_count_greater_than' and 'in_order' - and then chain them together:

bank.currencies.with_count_greater_than(10).in_order

You may also want to investigate SearchLogic, which implements many useful named scopes for you.

Upvotes: 1

BvuRVKyUVlViVIc7
BvuRVKyUVlViVIc7

Reputation: 11811

Maybe this helps you?

bank = Bank.first
concurrencies = Concurrency.find(:all, :conditions => {:bank => bank}, :order => "position desc")

Or you could change your bank model

def Bank << AR
  has_many :concurrencies

  def ordered_concurrencies
    Concurrency.for_bank(self)
  end
end

def Concurrency << AR
  belongs_to :bank

  named_scope :for_bank, lambda { |*args| {:conditions => {:bank => args.first}, :order => "position desc"} }
end

So you could call

Bank.first.ordered_concurrencies

and get the ordered concurrencies as ActiveRecord-Collection.

Beside this, with this solution you can add other conditions as well:

Bank.first.ordered_concurrencies.find(:all, :conditions => ["name like ?", "Dollar"])

Upvotes: 1

Related Questions