Ricevo uno strano comportamento durante il recupero delle raccolte da un'associazione has_many con le guide 3 quando si utilizza STI. Ho:Rails Associazione STI con sottoclassi
class Branch < ActiveRecord::Base
has_many :employees, class_name: 'User::Employee'
has_many :admins, class_name: 'User::BranchAdmin'
end
class User < ActiveRecord::Base
end
class User::Employee < User
belongs_to :branch
end
class User::BranchAdmin < User::Employee
end
il comportamento desiderato è che branch.employees
restituisce tutti i dipendenti, compresi gli amministratori di filiale. Gli amministratori filiali sembrano solo per essere 'caricato' in questa collezione, quando sono stati accede da branch.admins
, questo viene emesso dalla console:
Branch.first.employees.count
=> 2
Branch.first.admins.count
=> 1
Branch.first.employees.count
=> 3
Questo può essere visto in SQL generato, per la prima volta:
SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee') AND "users"."branch_id" = 1
e la seconda volta:
SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee', 'User::BranchAdmin') AND "users"."branch_id" = 1
ho potuto risolvere questo problema semplicemente specificando:
0.123.class Branch < ActiveRecord::Base
has_many :employees, class_name: 'User'
has_many :admins, class_name: 'User::BranchAdmin'
end
dal momento che tutti possono trovare dal loro branch_id ma questo crea problemi nel controller, se voglio fare branch.employees.build
allora la classe imposterà User
e devo incidere la colonna tipo da qualche parte. Ho risolto questo per ora con:
has_many :employees, class_name: 'User::Employee',
finder_sql: Proc.new{
%Q(SELECT users.* FROM users WHERE users.type IN ('User::Employee','User::BranchAdmin') AND users.branch_id = #{id})
},
counter_sql: Proc.new{
%Q(SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee', 'User::BranchAdmin') AND "users"."branch_id" = #{id})
}
ma vorrei davvero evitare questo se possibile. Qualcuno, qualche idea?
EDIT:
Il finder_sql e counter_sql non hanno realmente risolto per me perché sembra che le associazioni di genitori non usano questo e così organisation.employees
che has_many :employees, through: :branches
sarà di nuovo includere solo la classe User::Employee
nella selezione.
Questa è una bella cattura, grazie. La struttura del modello è stata effettivamente modificata in ogni caso, quindi il problema è scomparso, ma non credo che l'avrei considerato un effetto dell'ambiente! –