2010-03-05 6 views
4

Я пытаюсь понять, как создавать модели ActiveRecord с ассоциациями, которые могут дать те же результаты, как это SQL запрос:Как создать модели Rails с несколькими сложными ассоциациями/объединениями?

SELECT login, first_name, last_name, email_address 
FROM accounts 
INNER JOIN people ON person.id = accounts.person_id 
INNER JOIN email_address_people ON person.id = email_address_people.person_id 
INNER JOIN email_addresses ON email_address.id = email_address_people.email_address_id 
INNER JOIN email_address_types ON email_address_types.id = email_address_people.email_address_type_id 
WHERE email_address_types.email_address_type = 'account'; 

Структура таблицы, как следует, и предполагается, каждая таблица имеет id за нормальный ActiveRecord конвенции:

счета
ID: INT
person_id: INT
логин: строка

люди
ID: ИНТ
first_name: строка
last_name: строка

email_address_people
ID: ИНТ
person_id: INT
email_address_id: INT
email_address_type_id: Int

EMAIL_ADDRESSES
ID: ИНТ
email_address: струнный

email_address_types
ID: ИНТ
email_address_type: струнный

мне нужны модели, чтобы быть полностью функциональным, а не ограничивается вещами, как : find_by_sql.

Как создать связанные модели, которые делают это возможным?

Спасибо!
Крис Бенсон
[email protected]

ответ

0

Я думаю, что лучше всего сделать здесь, чтобы дать вам документацию первый: http://railsbrain.com/api/rails-2.3.2/doc/index.html
Посмотрите «has_many» (обращая внимание на: Through) и «BELONGS_TO» , а также «has_one», хотя я не думаю, что вы будете использовать позже.
This blog post поможет вам с has_many: через концепцию - и я думаю, после этого вы будете установлены. Дайте нам знать, если что-то непонятное!

class Account < ActiveRecord::Base 
    belongs_to :person 
end 

class Person < ActiveRecord::Base 
    has_many :accounts 
    has_many :email_addresses :through => :email_address_people 
end 

class EmailAddress < ActiveRecord::Base 
    belongs_to :email_address_type 
    belongs_to :person 
    has_one :email_address_type 
end 

class EmailAddressType < ActiveRecord::Base 
    has_many :email_addresses :through => :email_address_people 
end 

Я бы начал с этого. Это не проверено, но если мы увидим, какие перерывы, тогда мы можем это исправить ..:)

+0

Спасибо, но я уже это сделал. Знакомы со всеми из них - принадлежит_to, has_one, HABTM, HM: T. Уже используйте их все, но не можете понять, как сделать эту ситуацию правильной. Не нашли примеров в Интернете, которые согласуются с этой сложностью. Мог бы действительно использовать некоторый образец кода модели, который объединяет не менее 4-5 нормированных таблиц и использует их все в стандартном запросе. – Chris

+0

Отредактировал свой ответ (не уверен, если вы будете предупреждены об этом). – Trevoke

3

Попробуйте это:

классы моделей:

class EmailAddress < ActiveRecord::Base 
    end 

    class EmailAddressType < ActiveRecord::Base 
    end 

    class People < ActiveRecord::Base 
    has_many :accounts 
    has_many :email_address_people 
    has_many :email_addresses, :through => :email_address_people 

    has_many :account_email_address_people, 
        :class_name => "EmailAddressPeople", 
        :conditions => "email_address_type = 'account'" 

    has_many :account_email_addresses, 
        :through => :account_email_address_people 

    end 

    class EmailAddressPeople < ActiveRecord::Base 
    belongs_to :person 
    belongs_to :email_address 
    belongs_to :email_address_type 
    end 

Ваша учетная модель:

class Account < ActiveRecord::Base 
    belongs_to :person 

    # now to the actual method 
    def account_emails 
     person.account_email_addresses.map do |email| 
     [login, person.first_name, person.last_name, email.email_address] 
     end 
    end 

    # Brute force SQL if you prefer 
    def account_emails2 
     sql = "YOUR SQL HERE" 
     self.connection.select_values(sql) 
    end 

    end 

Если у вас есть объект Account в руке account.account_emails делает две базы данных вызовов:

  • Получить человек, используя идентификатор

  • Получить электронную почту счет для человека

Going непосредственно в базу данных (то есть. account.account_emails2) является самым быстрым вариантом, но это не путь Rails.

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