In meiner Anwendung hat ein Benutzer has_many Tickets. Leider hat die Ticket-Tabelle keine user_id: Sie hat eine user_login (es ist eine Legacy-Datenbank). Ich werde das irgendwann ändern, aber im Augenblick hätte diese Änderung zu viele Auswirkungen. Verband durch die Login Säule:Wie übergebe ich eine Zeichenfolge an einen Parameter has_many: finder_sql?
Wie kann ich eine „tickets Benutzer has_many“ bauen?
Ich habe versucht, die folgenden finder_sql, aber es funktioniert nicht.
class User < ActiveRecord::Base
has_many :tickets,
:finder_sql => 'select t.* from tickets t where t.user_login=#{login}'
...
end
ich einen seltsamen Fehler:
ArgumentError: /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:402:in `to_constant_name': Anonymous modules have no name to be referenced by
from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2355:in `interpolate_sql'
from /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:214:in `qualified_name_for'
from /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:477:in `const_missing'
from (eval):1:in `interpolate_sql'
from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:95:in `send'
from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:95:in `interpolate_sql'
from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/has_many_association.rb:143:in `construct_sql'
from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/has_many_association.rb:6:in `initialize'
from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations.rb:1032:in `new'
from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations.rb:1032:in `tickets'
from (irb):1
Ich habe auch versucht, diese finder_sql (mit Anführungszeichen um die Login):
:finder_sql => 'select t.* from tickets t where t.user_login="#{login}"'
Aber es die gleiche Art und Weise versagt (und sowieso , wenn es funktioniert, wäre es anfällig für SQL-Injektion).
In einer Testdatenbank, fügte ich eine user_id Spalte in der Karten-Tabelle und versucht, diese finder_sql:
:finder_sql => 'select t.* from tickets t where t.user_login=#{id}'
Jetzt das funktioniert gut. Offensichtlich hat mein Problem damit zu tun, dass die Benutzerspalte, die ich verwenden möchte, eine Zeichenfolge und keine ID ist.
Ich suchte das Netz für einige Zeit ... konnte aber keinen Hinweis finden.
ich jeden Parameter an die finder_sql passieren zu können, würde lieben, und schreiben Dinge wie diese:
has_many :tickets_since_subscription,
:finder_sql => ['select t.* from tickets t where t.user_login=?'+
' and t.created_at>=?', '#{login}', '#{subscription_date}']
Edit: foreign_key Parameter des has_many Vereinigung, weil meine Benutzer-Tabelle tut: Ich habe das nicht verwenden können, haben eine ID-Primärschlüsselspalte, die an anderer Stelle in der Anwendung verwendet wird.
Edit # 2: Offenbar habe ich die Dokumentation nicht gründlich genug gelesen: die has_many-Verbindung kann einen: primary_key-Parameter verwenden, um anzugeben, welche Spalte der lokale Primärschlüssel ist (Standard-ID). Danke Daniel, dass du meine Augen öffnest! Ich denke, es ist meine ursprüngliche Frage beantwortet:
has_many tickets, :primary_key="login", :foreign_key="user_login"
Aber ich würde noch gerne wissen, wie ich die has_many machen kann: tickets_since_subscription Verbandsarbeit.
OMG, ich kann nicht glauben, dass ich diese Option nicht gesehen habe, als ich die Dokumente 10 mal gelesen habe! Ich denke, ich brauche Ferien. Vielen Dank! :-) – MiniQuark