Synonym to Model?

Mam taki problem:
Mam tak zdefiniowany model i relacje:

Tabla Insurance zawiera dwa pola: Ubezpieczony i Płatnik. Obie odwołują się do modelu Person

  create_table "insurances", force: :cascade do |t|
    ....
    t.integer  "insured_id"
    t.integer  "payer_id"
    ...
  end

class Person < ActiveRecord::Base
  has_many :insureds, foreign_key: :insured_id, class_name: "Insurance", dependent: :destroy 
  has_many :payers, foreign_key: :payer_id, class_name: "Insurance", dependent: :destroy 
....
end


class Insurance < ActiveRecord::Base
  belongs_to :insured, class_name: "Person", foreign_key: :insured_id
  belongs_to :payer, class_name: "Person", foreign_key: :payer_id
.....
end

Wszystko to jakoś funkcjonuje…

Mogę oczywiście pisać

insurance.insured.name
insurance.payer.name …itp

ale…

Gdy mam taką definicję w Datatables ( https://github.com/antillas21/ajax-datatables-rails )

  def get_raw_records
    Insurance.joins( :group, :insured, :payer).includes(:insured, :payer).references(:group :insured, :payer).all
  end

, to tworzone jest zapytanie do ajax’a:

SELECT … FROM “groups” INNER JOIN “insurances” ON “insurances”.“id” = “groups”.“insurances_id” INNER JOIN “persons” ON “persons”.“id” = “insurances”.“insured_id” INNER JOIN “persons” “payers_insurances” ON “payers_insurances”.“id” = “insurances”."payer_id"

Zrozumiałe, bo tworzę połączenie dwa razy do tej samej tabeli.

Będę miał SELECT typu

insurance.number np 1234
group.name np “zwykła”
person.name np: “Kowalski Marian
person.address np 'Pścim Dolny”
payers_insurances.name np “Nowak Jan”
payers_insurances.address np “Wąchock”

i tutaj następuje kluczowa część mojego problemu.
Kolumny do wyszukiwania danych definiuje się jako:

@searchable_columns ||= %w(Insurance.number Group.name Person.name Person.address)

czyli nazwę MODELU, co zawsze mi zamieni na PERSON

A ja chciałby mieć możliwość wyszukania:
“%Kow%” po nazwisku Płatnika i
“%Wąch%” po adresie Ubezpieczonego.

Czyli SELECT … WHERE person.name LIKE “%Kow%” and payers_insurances.address LIKE “%Wąch%”

Czy ktoś ma może pomysł na to?
… bo nawet zdefiniowanie kolumn wyszukiwanie wg starej konwencji
( nie %w( Person.name … ) a [ “persons.name”…] generuje błąd, gdy definuję kolumnę przeszukiwania “payers_insurances.name”.
:frowning:

Kluczowe jest (chyba) tutaj:

Czyli, że w definicji przeszukiwanych kolumn należy podawać nazwę Modelu.

…I tutaj moje pytnia.

  1. Czy ktoś też miał problem budowania INNER JOIN dwa razy do tej samej tebeli po różnych polach?
  2. Czy ktoś też używa tego: https://github.com/antillas21/ajax-datatables-rails
    i jak ewentualnie definuje takie relacje?
  3. Czy w Railsach można tworzyć synonimy modeli?


Czy problem jest jednak poważny i te pytania, podobnie jak http://forum.rubyonrails.pl/t/dwie-relacje-wiele-do-wielu-do-jednego-modelu-i-wynik/

zostaną bez odpowiedzi?

Nie wiem czy da się jakoś łatwiej, przez metody z AR, ale na pewno da się ręcznie budując zapytanie Arel.

W AR mozna napisac samemu zapytanie w czystym sqlu, nie wiem czy jest mozliwosc aliasu tabeli podczas budowania zapytania przy pomocy modelu AR (ostatni raz z RoR korzystalem w wersji 3.0 a nie mam czasu zeby grzebac w dokumentacji) lub sprobuj poprzez Alias Model Name

Samo przedefiniowanie:

/models/insured.rb

class Insured < ActiveRecord::Base
  self.table_name = 'persons'
 
  has_many :insurances    
end

/models/payer.rb

class Payer < ActiveRecord::Base
  self.table_name = 'persons'
 
  has_many :insurances    
end

niczego nie da, bo w efekcie końcowym przykładowe payer.name i tak zostanie “wstrzyknięte” w SQL’a jako “persons.name”.

@Maciej ma rację, że trzeba zbudować zapytanie wykorzystując Arel…aczkolwiek w takim przypadku należy się w ogóle zastanowić nad stosowaniem pośrednika https://github.com/antillas21/ajax-datatables-rails

Póki co, po wymianie maili z autorem, znalazł on rozwiązanie, ale uznał to jako ciekawy przypadek użycia, wymagający zajęcia się w przyszłej wersji pakietu.

P.S.
Jeżeli komuś będzie potrzebna funkcjonalność sortowania i przeszukiwania kolumn, które pochodzą z tej samej tabeli, ale różnych połączeń zapytania select, to