Индекс мышления сфинкса с несколькими соединениями и условиями

У меня есть 3 модели: Users has_one Service и Users Has_many Phones (проверено или нет, уничтожено или нет)

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. Мне нужен логический атрибут, представляющий Службу, у пользователя которой есть один или несколько подтвержденных телефонов.

Итак, после прочтения этого сообщения я попробовал:

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

но пришлите мне ошибку «Неизвестный столбец 'verify_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, может ли кто-нибудь помочь мне решить эту проблему? Спасибо


person alex    schedule 02.01.2014    source источник


Ответы (2)


Второй подход - это то, что вам нужно - даже если вы присоединяетесь к специальной ассоциации, псевдонимом таблицы по умолчанию будет имя таблицы - следовательно, phone.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
person pat    schedule 02.01.2014
comment
Хорошо, я нашел проблему, ваше решение работает, как и мое второе. (Полный ответ в предложенном мной решении) - person alex; 04.01.2014

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

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!

person alex    schedule 03.01.2014