2015-01-21 3 views
1

Попытка создать ассоциацию has_one для этой проблемы. У меня есть две таблицы:Rails has_one с несколькими столбцами - has_many и has_one issue

Ca: 
    :id 
    :serial 
    ... 
Cert: 
    :id 
    :ca_id 
    :serial 
    ... 

Есть много сертификаты для данного cas.id, но только один сертификат для более КАН (: ca_id,: последовательный). Мне не нужна ассоциация has_many, но мне нужно has_one, чтобы я мог ссылаться на сертификат CA, используя ca.cert. Мне нужно HAS_ONE, чтобы создать что-то вроде следующего запроса:

SELECT * FROM где ca_id сертификаты = {ca.id} И последовательный = {} ca.serial

Для иллюстрации связи между ЦС и сертификаты -

  • единый центр сертификации имеет сертификат, идентифицирующий себя
  • Один CA имеет несколько сертификатов, которые он выдает конечным пользователям
  • A выдает сертификаты CA на основе своей собственной последовательности. Для простоты, начиная с 1 (сертификат CA будет иметь серийный номер 1, сертификаты конечных пользователей, выпущенные CA, начинаются с 2).
  • Сертификат принадлежит CA: ca_id и: serial
  • Сохранено несколько ЦС. Это означает, что два сертификата могут иметь один и тот же серийный номер, но должны принадлежать двум различным ЦС.

Illustration

Почему модель это так? Ну, cert-is-a-cert. Смысл структуры и функции аналогичен тому, является ли сертификат идентифицирующим CA или конечным пользователем.

Похоже, что has_one был бы прямолинейным, но я пробовал различные подходы с использованием областей, и это бесполезно.

Предоставлено, что я могу и создал метод «cert()» в модели cas, но похоже, что ассоциация должна быть возможной.

+0

Мой ответ может быть немного не ваш вопрос, почему вы настройке 'модель Cert' как для сохранения' id' & 'serial' его 'Ca'. Идентификатора будет достаточно. –

+0

@ TheChamp - CA имеет собственный сертификат. CA сертификаты конечного пользователя. Серии сертификатов представляют собой последовательности, основанные на данном ЦС, поэтому несколько сертификатов могут иметь один и тот же серийный номер, но будут принадлежать различным ЦС. Учитывая, что a-cert-is-a-cert, выпущенный для CA или выпущенный CA, я фактически имею два типа сертификатов в таблице. – Scott

+0

Хм, я сомневаюсь, что все это получится ... Разве это не более сложная проблема в вашей модели, если вы говорите, что у вас есть два типа сертификатов? Вы также можете [проверить STI] (http://samurails.com/tutorial/single-table-inheritance-with-rails-4-part-1/), что позволяет вам определять разные типы одной и той же модели. –

ответ

3

Вы можете определить HAS_ONE с областью:

class Ca < ActiveRecord::Base 
    has_many :certs 
    has_one :cert, ->{ joins(:ca).where('cas.serial = certs.serial')} 
end 

class Cert < ActiveRecord::Base 
    belongs_to :ca 
end 

Теперь

Ca.first.cert 

дает сертификат с соответствующими серийными.
Но это более элегантный и более Rails, чем определение:

class Ca < ActiveRecord::Base 
    has_many :certs 
    def cert 
    certs.where(serial: serial) 
    end 
end 
+0

Хороший, +1, является ли соединение (: ca) необходимым? –

+0

Блестящий! Это делает то, что я ищу. Вы, ребята, великолепны. Огромное спасибо. – Scott

+0

@ TheChamp yes, без 'joins()', Rails просто выберет из сертификатов. 'Joins()' делает таблицу 'cas' доступной для предложения' where'. –

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