2009-01-06 32 views
22

Một câu hỏi Rails cơ bản khác:Giàn giáo ActiveRecord: hai cột cùng loại dữ liệu

Tôi có bảng cơ sở dữ liệu cần tham chiếu đến chính xác hai bản ghi khác nhau của một loại dữ liệu cụ thể.

Ví dụ giả thuyết: Tôi đang tạo cơ sở dữ liệu trò chơi điện tử. Tôi có một bảng cho "Các công ty". Tôi muốn có chính xác một nhà phát triển và chính xác một nhà xuất bản cho từng mục nhập "Trò chơi điện tử".

Tôi biết rằng nếu tôi muốn có một công ty, tôi chỉ có thể làm một cái gì đó như:

script/generate Videogame company:references 

Nhưng tôi cần phải có cả hai công ty. Tôi không muốn sử dụng một bảng tham gia, vì chỉ có thể có chính xác hai loại dữ liệu đã cho và tôi cần chúng phải khác biệt.

Có vẻ như câu trả lời phải khá rõ ràng, nhưng tôi không thể tìm thấy nó ở bất cứ đâu trên Internet.

Trả lời

45

Chỉ cần để mọi thứ gọn gàng lên một chút, trong việc di chuyển của bạn, bạn có thể bây giờ cũng làm:

create_table :videogames do |t| 
    t.belongs_to :developer 
    t.belongs_to :publisher 
end 

Và kể từ khi bạn đang gọi điện thoại các phím developer_id và PUBLISHER_ID, mô hình nên có lẽ là:

belongs_to :developer, :class_name => "Company" 
belongs_to :publisher, :class_name => "Company" 

Nó không phải là một vấn đề lớn, nhưng tôi thấy rằng như số lượng các hiệp hội với các đối số thêm được thêm vào, những điều ít rõ ràng trở nên, vì vậy tốt nhất là dính vào các giá trị mặc định bất cứ khi nào có thể.

+0

Tôi đã thử điều này và hiện có developer_id nhưng không thể truy cập game.developer. Tôi có trong lớp trò chơi điện tử của tôi attr_accessible: developer. – quantumpotato

+0

Điều này có lẽ đã được giải quyết rồi, nhưng bạn đã thêm has_many: games (hoặc một cái gì đó tương tự) vào mô hình phát triển của bạn chưa? – MrWater

+0

Làm cách nào để thực hiện ánh xạ ngược? –

9

Tôi không biết làm thế nào để thực hiện việc này bằng tập lệnh/tạo.

Ý tưởng cơ bản dễ thấy hơn mà không cần sử dụng tập lệnh/tạo. Bạn muốn có hai trường trong bảng/mô hình trò chơi điện tử của bạn giữ khóa ngoài cho bảng/mô hình công ty.

Tôi sẽ cho bạn thấy những gì tôi nghĩ rằng mã sẽ giống như thế, nhưng tôi chưa thử nghiệm, vì vậy tôi có thể sai.

tập tin chuyển đổi của bạn có:

create_table :videogames do |t| 
    # all your other fields 
    t.int :developer_id 
    t.int :publisher_id 
end 

Sau đó, trong mô hình của bạn:

belongs_to :developer, class_name: "Company", foreign_key: "developer_id" 
belongs_to :publisher, class_name: "Company", foreign_key: "publisher_id" 

Bạn cũng có đề cập đến mong muốn hai công ty là khác nhau, mà bạn có thể xử lý trong một xác nhận trong các mô hình mà kiểm tra xem developer_id != publisher_id.

+0

Là một phụ đề, tham số Foreign_key ở đây là không cần thiết, vì mặc định là tên của liên kết + "_id". Để biết thêm, hãy xem http://www.spacevatican.org/2008/5/6/creating-multiple-associations-with-the-same-table/ –

2

Nếu có bất kỳ phương pháp hoặc xác thực nào bạn muốn cụ thể cho một loại công ty nhất định, bạn có thể phân loại mô hình công ty phụ. Điều này sử dụng một kỹ thuật được gọi là thừa kế bảng đơn. Để biết thêm thông tin kiểm tra bài viết này: http://wiki.rubyonrails.org/rails/pages/singletableinheritance

Sau đó bạn sẽ có:

#db/migrate/###_create_companies 
class CreateCompanies < ActiveRecord::Migration 
    def self.up 
    create_table :companies do |t| 
     t.string :type # required so rails know what type of company a record is 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :companies 
    end 
end 

#db/migrate/###_create_videogames 
class CreateVideogames < ActiveRecord::Migration 
    create_table :videogames do |t| 
    t.belongs_to :developer 
    t.belongs_to :publisher 
    end  

    def self.down 
    drop_table :videogames 
    end 
end 

#app/models/company.rb 
class Company < ActiveRecord::Base 
    has_many :videogames 
    common validations and methods 
end 

#app/models/developer.rb 
class Developer < Company 
    developer specific code 
end 

#app/models/publisher.rb 
class Publisher < Company 
    publisher specific code 
end 

#app/models/videogame.rb 
class Videogame < ActiveRecord::Base 
    belongs_to :developer, :publisher 
end 

Kết quả là, bạn sẽ phải Company, nhà phát triển và các mô hình xuất bản để sử dụng.

Company.find(:all) 
Developer.find(:all) 
Publisher.find(:all) 
Các vấn đề liên quan