Trong ứng dụng của tôi, một người dùng có_many vé. Thật không may, bảng vé không có user_id: nó có user_login (nó là một cơ sở dữ liệu kế thừa). Tôi sẽ thay đổi một ngày nào đó, nhưng bây giờ thay đổi này sẽ có quá nhiều ý nghĩa.Làm cách nào để chuyển một chuỗi tới tham số has_many: finder_sql?
Vậy làm cách nào tôi có thể tạo liên kết "người dùng has_many: vé" thông qua cột đăng nhập?
Tôi đã thử finder_sql sau, nhưng nó không hoạt động.
class User < ActiveRecord::Base
has_many :tickets,
:finder_sql => 'select t.* from tickets t where t.user_login=#{login}'
...
end
tôi nhận được một lỗi lạ:
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
Tôi cũng đã cố gắng finder_sql này (với dấu ngoặc kép quanh đăng nhập):
:finder_sql => 'select t.* from tickets t where t.user_login="#{login}"'
Nhưng nó không giống như vậy (và dù sao , nếu nó làm việc nó sẽ dễ bị tiêm sql).
Trong một cơ sở dữ liệu kiểm tra, tôi đã thêm một cột user_id trong bảng vé, và cố gắng finder_sql này:
:finder_sql => 'select t.* from tickets t where t.user_login=#{id}'
Bây giờ này hoạt động tốt. Vì vậy, rõ ràng, vấn đề của tôi đã làm với thực tế là cột người dùng tôi đang cố gắng sử dụng là một chuỗi, không phải là một id.
Tôi đã tìm kiếm trên mạng trong một thời gian khá ... nhưng không thể tìm thấy manh mối.
Tôi rất thích để có thể vượt qua bất kỳ tham số cho finder_sql, và viết những điều như thế này:
has_many :tickets_since_subscription,
:finder_sql => ['select t.* from tickets t where t.user_login=?'+
' and t.created_at>=?', '#{login}', '#{subscription_date}']
Chỉnh sửa: Tôi có thể không sử dụng: thông số foreign_key của hiệp hội has_many vì người dùng của tôi bảng làm có một cột khóa chính id, được sử dụng ở nơi khác trong ứng dụng.
Chỉnh sửa # 2: dường như tôi không đọc tài liệu đủ kỹ lưỡng: liên kết has_many có thể lấy tham số: primary_key, để chỉ định cột nào là khóa chính cục bộ (id mặc định). Cảm ơn Daniel vì đã mở mắt ra! Tôi đoán nó sẽ trả lời câu hỏi ban đầu của tôi:
has_many tickets, :primary_key="login", :foreign_key="user_login"
Nhưng tôi vẫn muốn biết cách tôi có thể thực hiện công việc liên kết has_many: ticket_since_subscription.
OMG, tôi không thể tin rằng tôi không thấy tùy chọn này khi tôi đọc tài liệu 10 lần! Tôi nghĩ rằng tôi cần một số kỳ nghỉ. Cảm ơn bạn rất nhiều! :-) – MiniQuark