2014-01-02 1 views
2

У меня есть 3 модели: пользователи HAS_ONE службы и пользователей HAS_MANY телефоны (проверен или нет, уничтоженных или нет)Думая индекс сфинкс с несколькими объединениями и условие

Class Phone < ActiveRecord::Base 
    belongs_to :user 
end 

class User < ActiveRecord::Base 
    has_one :service 
    has_many :phones 
    has_many :verified_phones, -> {where('verified_at IS NOT NULL AND destroyed_at IS NULL')}, class_name: 'Phone' 
end 

class Service < ActiveRecord::Base 
    belongs_to :user 
    has_many :phones, through: :user 
    has_many :verified_phones, through: :user 
end 

Я хотел бы определить в TS-индекс по модель Service. Я хочу атрибут boolean-faceted, который представляет Сервис, пользователь которого имеет один или несколько подтвержденных телефонов.

Так после reading this post I tried:

join verified_phones 
has 'COUNT(verified_phones.id) > 0', as: :user_phone_verified, type: :boolean, facet: true 

но отправить мне ошибку «Неизвестный столбец„verified_phones.id“в" списке поля»(та же ошибка произошла в посте)

Тогда я пытался

join verified_phones 
has 'COUNT(phones.id) > 0', as: :user_phone_verified, type: :boolean, facet: true 
-> but result are wrong : attribute is true for every user that have a phone, verified or not, destroyed or not. 

Затем я попытался

join phones 
has 'COUNT(phones.verified_at IS NOT NULL AND phones.destroyed_at IS NULL) > 0', as: :user_phone_verified, type: :boolean, facet: true 

-> та же проблема: атрибут истинен для каждого пользователя, у которого есть телефон, проверен или нет, уничтожен или нет.

Я плохо разбираюсь в синтаксисе SQL, может ли кто-нибудь помочь мне решить эту проблему?

ответ

1

Второй подход - это то, что вам нужно - даже если вы присоединяетесь к специальной ассоциации, псевдоним таблицы будет именем таблицы по умолчанию - следовательно, phones.id.

Тем не менее, то, что возвращается, кажется, не так. Возможно, следующий вместо:

join verified_phones 
has "SUM(CASE WHEN phones.id IS NULL THEN 0 ELSE 1 END) > 0", 
    as: :user_phone_verified, type: :boolean, facet: true 
+0

OK Я нашел проблему, ваше решение работает, и поэтому мой второй. (Полный ответ в моем предлагаемом решении) – alex

1

Я получил его: я должен был быть более точным с синтаксисом моего определения ассоциации:

has_many :verified_phones, -> {where('verified_at IS NOT NULL AND destroyed_at IS NULL')}, class_name: 'Phone' 

должен быть:

has_many :verified_phones, -> {where('phones.verified_at IS NOT NULL AND phones.destroyed_at IS NULL')}, class_name: 'Phone' 

Моих Модель пользователя имеет тот же атрибут «destroy_at» -> созданный SQL искал этот атрибут в неправильной таблице.

Так что с этой коррекции и синтаксис работы:

мой первоначальный:

join verified_phones 
has 'COUNT(phones.id) > 0', as: :user_phone_verified, type: :boolean, facet: true 

или предложенный @Pat:

has "SUM(CASE WHEN phones.id IS NULL THEN 0 ELSE 1 END) > 0", 
    as: :user_phone_verified, type: :boolean, facet: true 

Но я не очень комфортабельный с этим, потому что Я вижу возможную путаницу с этим псевдонимом таблицы, который по-прежнему называется «телефоны». Что произойдет, если мне нужно присоединиться к тем же телефонам с индексом и проверенным телефонам?

Но пока это решит мою проблему, так что спасибо @Pat!