2012-02-26 3 views
0

Может ли кто-нибудь сказать мне, как упростить следующую функцию в моей модели Invoice? Он должен вернуть все Invoices, связанные с конкретным Client (оба подключены через таблицу Projects).Пожалуйста, помогите мне упростить эту простую функцию Ruby on Rails

def self.search_by_client_id(client_id) 
    if client_id 
    projects = Project.where(:client_id => client_id) 
    Invoice.where(:project_id => projects) 
    else 
    scoped 
    end 
end 

Я действительно не могу обдумать это. Спасибо за любой вклад!

ответ

3

Это похоже на прекрасную возможность для прицела!

scope :client, lambda{|id| includes(:projects).where('projects.client_id = ?', id)} 

Invoice.client(4).all # returns all invoices for the client with the specified ID. 
+0

О да, вы правы. У меня вроде было чувство кишки ... – Tintin81

+0

Единственная проблема в том, что мне нужно объединить несколько функций поиска в моем контроллере, например: '@invoices = current_user.invoices.includes (: project) .search_by_number (params [ :. запрос]) search_by_project_id (PARAMS [:. project_id]) search_by_client_id (PARAMS [: client_id]) '. И эти поиски должны быть подключены в SQL через * OR *, а не * AND *. Значит, я не могу использовать области здесь? – Tintin81

+0

Gosh, я просто понимаю, как уродливый мой код контроллера ... – Tintin81

1

Если я правильно понимаю ваш вопрос, вы должны быть в состоянии сделать это с помощью ActiveRecord ассоциации:

class Client < ActiveRecord::Base 
    has_many :projects 
    has_many :invoices, :through => :project 
end 

class Project < ActiveRecord::Base 
    has_many :invoices 
    belongs_to :client 
end 

class Invoice < ActiveRecord::Base 
    belongs_to :project 
    has_one :client, :through => :project 
end 

Тогда все Invoices, связанные с конкретной Client:

@client.invoices 

Для получите Client, связанный с конкретным счетом:

@invoice.client 
+0

Спасибо! Но по какой-то причине я не могу заставить ваши последние две строки работать в моей модели. – Tintin81

+0

Я думаю, что у Саймона отсутствует ассоциация в классе Project. Он должен включать «own_to: client». Это позволит счету получить доступ к клиенту через проект. –

+0

Да, согласен. Но что, если я хочу использовать разные поиски в моем контроллере, например? '@invoices = current_user.invoices.includes (: project) .search_by_number (params [: query]). search_ by_project_id (params [: project_id]). search_by_client_id (params [: client_id])' Разве это не беспорядочно ? Было бы хорошо решить это в модели как-то ... – Tintin81

Смежные вопросы