2010-09-17 31 views
7

Tôi đã xây dựng một ứng dụng Rails thực hiện chức năng kế toán. Là một phần của điều này, tôi có một mô hình với tên lớp là Transaction. Cho đến nay rất tốt, tôi đã xây dựng chức năng này trong một tháng hoặc lâu hơn và mọi thứ đang hoạt động như mong đợi.Giải quyết xung đột tên lớp trong ứng dụng Rails

Cho đến bây giờ ...

Tôi vừa phát hiện một số chức năng báo cáo cũ hơn được phát triển tháng trước bằng thư viện Ruport đã ngừng hoạt động. Có vẻ như Ruport, khi tạo tệp PDF, yêu cầu thư viện cũng có một lớp/mô-đun có tên là Transaction.

TypeError in Admin/team reportsController#generate 
Transaction is not a module 

... 

This error occurred while loading the following files: 
    pdf/writer 
    transaction/simple 

Vì vậy, tôi đang tìm cách khắc phục nhanh ở đây. Một hy vọng không liên quan đến việc đổi tên mô hình Transaction của mình và tái cấu trúc mã giá trị trong vài tuần qua.

Mong một số gợi ý thông minh :)

Trả lời

7

Tôi tin rằng vấn đề là xuống Ruport đòi hỏi PDF :: Writer gem, mà lần lượt yêu cầu Transaction :: Simple gem xác định giao dịch module.

Có chắc chắn là một phương pháp #transaction trong ActiveRecord, nhưng tôi không nghĩ rằng có một mô-đun giao dịch hoặc lớp trong Rails. Tôi sẽ rất vui khi được sửa chữa trên cái đó.

Không gian tên thường là phương pháp hay nhất để tránh đặt tên xung đột như thế này. Ví dụ.

module Account 
    class Transaction < ActiveRecord::Base 
    .... 
    end 
end 

Tuy nhiên, việc đặt tên các mô hình ActiveRecord có thể làm phát sinh các vấn đề khác.

Vì mất nhiều thời gian, việc đổi tên kiểu giao dịch của bạn có thể là đặt cược tốt nhất.

Bạn vẫn có thể giữ bảng cơ sở dữ liệu giao dịch hiện tại nếu muốn, vì vậy việc di chuyển của bạn không cần thay đổi, bằng cách đặt self.table_name = "transactions" bên trong mô hình của bạn.

Các liên kết của bạn với các mô hình khác vẫn có thể được đặt tên là "giao dịch" bằng cách chỉ định class_name trong cuộc gọi liên kết của bạn. Ví dụ.

class User < ActiveRecord::Base 

    has_many :transactions, :class_name => "AccountTransaction" 

end 

Hai đề xuất đó có thể hoặc có thể không giúp bạn tiết kiệm thời gian.

+0

Cảm ơn. Tôi đã thay đổi câu trả lời của bạn cho câu trả lời được chấp nhận vì nó mô tả chính xác hơn vấn đề cụ thể mà tôi có - mặc dù Yannis, câu trả lời cũng chính xác! Cuối cùng tôi sử dụng để đổi tên mô hình, bảng cơ sở dữ liệu và tất cả các liên kết bằng cách sử dụng một số skool cũ tìm và thay thế;) – aaronrussell

+0

Trong phiên bản mới hơn của Rails, 'set_table_name' chỉ là' self.table_name = ', xem http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name-3D –

0

Vấn đề của bạn có thể xuất phát từ thực tế giao dịch đó cũng là một từ dành riêng trong Rails ...

+0

Có phải không? Chỉ trích! Nhưng cảm ơn vì đã thông báo cho tôi ... – aaronrussell

+4

Rails chỉ là một thư viện Ruby, nó không thể thêm bất kỳ từ khóa nào vào ngôn ngữ Ruby. –

+1

Nó có thể chỉ là một thư viện, nhưng nó có thể áp đặt các giới hạn về việc đặt tên của những thứ sử dụng nó (mặc dù đây là nguyên nhân không được thi hành bởi ngôn ngữ).Chỉ cần nhìn vào những rắc rối bạn nhận được trong khi cố gắng sử dụng tên cột 'loại' ... –

13

Đã được trả lời và cũ, nhưng tôi đến đây với cùng một vấn đề, nhưng đã giải quyết nó theo một cách khác.

Tôi có hai Mô hình có tên là Kéo và truy vấn. Cố gắng tham chiếu Query.some_static_method() trong một phương thức trong Pull dẫn đến Truy vấn giải quyết thành ActiveRecord::AttributeMethods::Query:Module.

Giải quyết bằng cách đặt không gian tên trống ở phía trước với ::Query.some_static_method()

+0

Câu trả lời hay, không biết về vùng tên trống! –

+0

Giải pháp thanh lịch. Bạn có thể giải thích chính xác lý do tại sao/nó hoạt động như thế nào? – cph2117

+0

@ cph2117, tất cả những gì thực sự làm là rõ ràng về không gian tên nào là để tìm 'Truy vấn'. – hometoast

Các vấn đề liên quan