Geçenlerde Raylar 4.1 ila 4.2 Rails için yükseltilmiş ve yanlışlıkla bu tür alıyoruz çünkü Arel + ActiveRecord kullanarak sorunları görüyoruz:Arel + Raylar 4.2 neden sorunları (bağlamaları kayıp olmak üzere)
ActiveRecord::StatementInvalid: PG::ProtocolViolation: ERROR: bind message supplies 0 parameters, but prepared statement "" requires 8
İşte kırılıyor kodu: Biz sorgunun ilk bölümünü çözmek için nasıl düşündüm
customers = Customer.arel_table
ne_subquery = ImportLog.where(
importable_type: Customer.to_s,
importable_id: customers['id'],
remote_type: remote_type.to_s.singularize,
destination: 'hello'
).exists.not
first = Customer.where(ne_subquery).where(company_id: @company.id)
second = Customer.joins(:import_logs).merge(
ImportLog.where(
importable_type: Customer.to_s,
importable_id: customers['id'],
remote_type: remote_type.to_s.singularize,
status: 'pending',
destination: 'hello',
remote_id: nil
)
).where(company_id: @company.id)
Customer.from(
customers.create_table_alias(
first.union(second),
Customer.table_name
)
)
gibi Customer.where içinde olması exists.not taşıyarak (bağlamaları olmamasından aynı raylar hata içine çalıştıran) öyleyse:
Buçalışır gibiydi ama biz bu kod satırı ile aynı konuda koştu:
first.union(second)
biz sorguda bu bölümü her çalıştırdığınızda
, bağlamaları kaybolur. Birincisi ve ikincisi aktif kayıt nesneleridir, ama biz onları "birleştirmek" olarak, bağları kaybeder arel nesneleri haline gelir.Sorgu boyunca bisiklet sürmeyi denedik ve bağlantıları manuel olarak değiştirdik ancak düzgün çalıştığını göremedik. Bunun yerine ne yapmalıyız?
DÜZENLEME: Ayrıca şöyle arel nesnesinde değiştirilmesi elle daha sonra birinci ve ikinci, ve gelen bağlanma değerleri çıkarılarak çalıştı
:
union.grep(Arel::Nodes::BindParam).each_with_index do |bp, i|
bv = bind_values[i]
bp.replace(Customer.connection.substitute_at(bv, i))
end
Bununla birlikte, başarısız olduğundan,:
NoMethodError: undefined method `replace' for #<Arel::Nodes::BindParam:0x007f8aba6cc248>
Bu, raylar github repo'da önerilen bir çözümdü.
Bazı sorguların daha iyi yazılabileceğini düşünüyorum (örneğin: second = Customer.joins (: import_logs) .where (import_logs: {/ * ImportLog conditions here * /})) ... başarmaya çalışıyorsun. – muZk